We have been busy developing our new baby JiraTouch for the last 3 months. It has been a tough journey with lots of unknowns and new things. Platform was new, development tools were new and the team was new. The only knowns were Jira and the C# language. I would like to share some of my observations in this blog post.
What is JiraTouch?
You can read JiraTouch features to learn more about JiraTouch.
You can watch video tutorials to see JiraTouch in action.
You can buy JiraTouch from AppStore.
Jira and SOAP API
No need to talk about the quality of Jira software on its own. But I'm sorry that Jira SOAP API is not as complete as the product itself. The most serious problem is the versioning dilemma of the SOAP API. SOAP API is introduced since Jira version 3.0 but over the time (Recent version is Jira 4.01) there have been lots of changes with the API. Change is normal and we do not expect all aspects shall be covered at once, since the product itself matures and changes so does the SOAP API. But I would be more happy if Jira guys developed a good API versioning strategy with good API change documentation. For example with no specific versioning information included in the wsdl you get different properties for the same Type. One perfect example is RemoteComment type, this type has changed dramatically through Jira versions. Here are examples of the WSDL for different jira versions
This snippet is from the wsdl of a Jira 3.6 installation
<element name="body" nillable="true" type="xsd:string"/>
<element name="id" nillable="true" type="xsd:string"/>
<element name="level" nillable="true" type="xsd:string"/>
<element name="timePerformed" nillable="true" type="xsd:dateTime"/>
<element name="username" nillable="true" type="xsd:string"/>
This is wsdl snippet for RemoteComment from Jira 4.01
<element name="author" nillable="true" type="xsd:string"/>
<element name="body" nillable="true" type="xsd:string"/>
<element name="created" nillable="true" type="xsd:dateTime"/>
<element name="groupLevel" nillable="true" type="xsd:string"/>
<element name="id" nillable="true" type="xsd:string"/>
<element name="roleLevel" nillable="true" type="xsd:string"/>
<element name="updateAuthor" nillable="true" type="xsd:string"/>
<element name="updated" nillable="true" type="xsd:dateTime"/>
Another very major difficulty I think is how Jira handles/expects date and time values. When you get some entity having datetime data from Jira with the SOAP API, you get UTC formatted datetime value and that is ok. But since some specific Jira versions does not provide information about the Jira server's datetime we are not able to perform timezone specific conversions which in turn causes our clients to view wrong or more specifically locale datetime values and as well submit locale datetimes to the Jira server. To handle this deficiency we had to include in JiraTouch a time zone selection if we could not get server datetime automatically from Jira server, which is an extra configuration overhead for our clients. Jira's date and time handling is long debate in Jira community and among Jira customers as well, current Jira versions can not handle different time zones as far as we investigated Jira customers have requirements about this concern and we hope Jira guys will develop a smart way to handle different timezonse at some point.
Custom fields were another headache. Jira has very handy and highlghy configurable custom field support. You can define most of the custom fields you need, but SOAP API has limited support for the custom fields. One major problem is you get dictionary of custom fields for a RemoteIssue type but you just have custom field id and the value, there is no label/name included.
Here is the wsdl definition for a remote custom field
<element name="customfieldId" nillable="true" type="xsd:string"/>
<element name="key" nillable="true" type="xsd:string"/>
<element name="values" nillable="true" type="impl:ArrayOf_xsd_string"/>
Since you get no label what shall we display to the user the id and the current value? Not so user friendly. The only way to get label/name of the custom fields is through getCustomFields soap method, but there is one little problem you have to be logged in as an administrative user in order to call that method! That is not so cool but with some tweaking we could overcome this limitation without requiring adminsistrative login.
The last thing I want to point about Jira SOAP API limitations is that mighty "time tracking" field dilemma, more generally some explicitly required but not included on RemoteIssue type properties. These properties are somehow predefined custom system fields but createIssue method of SOAP API does not support these kind of fields properly. Again to overcome this issue some little fancy tricks need to be done.
These were some of the problems we faced with the well known part of the project.
Mono, MonoDevelop and MonoTouch
I believe that Mono and MonoTouch are very valuable efforts. I will not waste your time telling you why they are valuable you can find lots of arguments around, but as a Microsoft platform developer and a .NET developer I'm pleased with the existence of Mono and MonoTouch.
The major headache we had during JiraTouch development regarding Mono was MonoDevelop. Compared to Visual Studio MonoDevelop feels like a not so cool notepad. The worst thing about MonoDevelop is unstability, it might crash, freeze or code editor just decide not to paint some of the brackets you type. For example if you reference assemblies with auto incremented version numbers (that is 1.0.*) MonoDevelop can not refresh your references successfully and as a result you get "missing type" compile time errors. MonoDevelop debugger also has some problems, you may need to click multiple times so that debugger can be attach to IPhone simulator, MonoDevelop may crash while you try to evaluate a variable during debugging, you may get "Can not evaluate" error while trying to see variable values and you can not just copy/paste the contents of the evaluation window.
We designed JiraTouch so that we could develop Model and UI assemblies seperately, so for a long time we tried to develop Model assembly on OpenSUSE with MonoDevelop to ensure maximum level of framework compatibility when we reference that assembly from the UI (IPhone application actually) which was being developed on Mac OSX. After spending some time struggling with MonoDevelop we decided to switch to Visual Studio and do rest of the Model assembly development with Visual Studio which in turn caused some framework incompatibilities I will demonstrate you just in a second.
Another major problem was missing System.Web.Services.dll in MonoTouch. During development we used to generate Jira service proxy on openSUSE, include the generated code in the project and reference an unofficial version of System.Web.Services.dll. That approach worked well for a while until we decided to compile our IPhone application with "Link SDK assemblies only" option which caused our approach to fail. So we had to give up with that linker option and try to survive with a larger application size, until Mono decided to include an official System.Web.Services.dll for MonoTouch which just worked well with the linker option.
We faced framework level implementation differences as a result of choosing Visual Studio as the main tool for Model development. The biggest issue we faced was with XmlReader and XmlTextWriter implementations. In Microsoft's implementation WriteNode works perfectly with element attributes while Mono implementation just writes the first attribute and ommits the rest. So we had to traverse all elements and perform WriteAttributes, WriteRaw, WriteStartElement and WriteFullEndElement based on the element types. This difference was hard to discover and hard to resolve which we had to spend much more time than we expected.
Yet another frameowork level implementation difference was with HttpWebRequest.PreAuthenticate we faced while developing the Social integration parts of JiraTouch. On Microsoft and Mono when you specify PreAuthenticate to be true and add an Authorization header to the request both frameworks continue to send that header to the server after the first request, but on MonoTouch Authorizaton header is not sent to the server after the first request which is absolutely a normal behaviour. Again this difference caused us couple of frustrating debug sessions, but we are happy that we discovered that issue before launching JiraTouch.
The last difficulty we faced I want to mention is that magic "Link SDK assemblies only" option. If you build you IPhone application with this switch MonoTouch performs some optimizations during compile time thus producing a smaller application in size. Smaller size means a lot in iTunes and AppStore world, because if your application(actually ipa file, which is compressed package of your application) is larger than 10MB you will not be listed for OTA downloads which in turn means that you will not reach some portion of IPhone users. So we decided to use this option, but we ignored some facts about using this options and Mono documentation does not specify exactly what considerations apply if we use this options. It is simply stated that some of the reflection and serialization related functionality can cause runtime errors. Yes that is true we had runtime errors but we would be pleased if the compiler could warn us about these issues. One simple example was the runtime error we got from a code snippet which was simply performing Linq query on an array of enumerations. The code was something like this
var enums = Enum.GetValues(typeof(SomeEnumerarion));
var selectedValue = from e in enums where e.ToString() == "EnumValue1" select e;
The sample code snippet worked well while debugging with "Link SDK assemblies only" option but when we tested JiraTouch on an IPhone we used to get runtime errors regarding MonoTouch and AOT (ahead of time compiling, since on IPhone JIT compilation can not be performed MonoTouch uses AOT compiling to support generics, linq and other stuff). We just changed the code and dropped the Linq query and the problem was solved. As I said we would be happier if MonoTouch compiler warned us with that possible runtime problem.
Review Process; iTunes and AppStore
We had no problems during the process of submitting JiraTouch for review over iTunes. We submitted on the weekend and JiraTouch status changed to "In Review" on Tuesday and we got approved on Friday. We got the approval within 3 days that was amazing.
What is our vision?
We argue that JiraTouch is the most complete Jira client specifically optimized for IPhone. We tried to cover most of the Jira functionality so that a Jira user can perform almost everything with JiraTouch. We believe that we succeeded to get to that completeness level as far as Jira SOAP API allowed us and a little bit beyond what Jira SOAP Api offers. Our vision was to provide the highest possible level of Jira functionality with some unique features like Social integration, which allows JiraTouch users to update their twitter,facebook, linkedin and yammer accounts.
In the future we intend to provide more unique features to JiraTouch users, which will be focused mainly on sharing and social communities. We already started evaluating these unique ideas and hope to include these fatures with the next version of JiraTouch.
What is PragmaTouch?
We decided to gather all touch enabled device software development under the PragmaTouch brand. PragmaTouch will be the brand supporting primarly JiraTouch. We will provide consulting and developing custom touch enabled device projects under PragmaTouch brand as a group of independent software developers.
I would like to thank to my colleagues Tolga and Ahmet. They did a fantastic job and helped me much while managing this project.