Wednesday, August 24, 2011

Android and iPhone apps in sync - here are the code results

I sent the Android version of my app off to QA yesterday. Both the iPhone and Android versions are now in sync and here are some code stats.

*.m   100 files   589,431 bytes
*.h   109 files   123,079 bytes
      =========   =============
      209 files   712,510 bytes


*.java 97 files   633,177 bytes

A lot more comments in the Java code as I have JavaDoc comments over each method but even with that the code base is a lot smaller and a lot less files. Anytime you have less code and less files it is easier to maintain and will tend to have less bugs.

I was surprised at how quickly the conversion went. A couple of things play into that, first I started on the more difficult of the two platforms - the iPhone. It is more difficult due to my experience with Objective C and the Mac in general. Some things are easier on the iPhone such as only having one screen size to deal with. Second once you have the database schema in place and the logical layout of the program ready to roll you are doing more straight coding and less designing.

Doing double development has some benefits. There are things on each platform that are pretty easy to do. They force you to look for a solution on the other platform. I don't want either version to outshine the other. The end user should be able to pick up any device with the app installed and be able to use it. There are differences in button placement - iPhone on bottom, Android on top - and the iPhone always has the "Back" operation as a button on screen where Android users know to press the dedicated back button on the device.

Programming differences

  • I found programming for SQLite much simpler on the Android. I pretty much had to build SQL statements by scratch on the iPhone and pass them off to the database. The Android helper methods make this much easier. Android made it super simple to handle cursor data in a scrolling list. All of that had to be written manually under iOS. 
  • I had to write the multi-part entity code to send images to the server on the iPhone where I was able to use the Apache libraries under Android.
  • Hiding buttons on a toolbar is as simple as setting visibility state on Android. Under iOS I had to totally recreate the toolbar for each unique button layout. Some views are reused for editing vs. viewing of the same data. I needed to hide buttons such as [Save] in the read-only version.
  • The home screen with icons laid out in 2x3 for portrait and 3x2 for landscape was easier to do on Android as I just defined two XML layouts and put them in the proper directories. All of this had to be done in code on the iPhone although I was able to use the animation framework to have a cool looking transition under iOS that I did not port to the Android.
  • Handling JPG images was easier on iOS. Pretty simple access to camera, gallery and image viewer. It was also simple to get to the raw data to store in blobs under SQLite.
  • Doing background / busy threads is much easier under Android. On the iPhone you have to control everything, shut off the UI, get the spinning gear going, dimming screen, etc. On Android I just put the busy work in an async activity and invoked it.
  • Date manipulation is much easier in Java. The method names make sense  startDate.after(endDate) where it is [startDate timeIntervalSinceDate:endDate] > 0 on iOS. 
  • Settings seconds to zero startData.set(Calendar.SECONDS, 0);  for Android and    NSTimeInterval time = floor([startDate timeIntervalSinceReferenceDate] / 60.0) * 60.0;  startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:time]; for iOS
  • iOS wins for speed of simulator (much faster than actual device) and speed when running in debugger but Android wins for actually being able to see variable values, do ad hoc expression evaluation while in debugger and separating output log messages into tabs in the LogCat output window.
  • Android wins for being able to run on a multitude of devices via one code base. I have run it on various phones, the older Samsung Galaxy Tablet and a Motorola Xoom. The iOS version is for the iTouch and iPhone. I can run it on the iPad but only as a double pixel app. Some call it fragmentation but with very few program tweaks having the ability to run on a variety of hardware is just fine with me. Heck I do that with PC programs all the time. I rarely know the monitor resolution up front. Use the space you are given.
  • Easier to view the SQLite database under iOS. I used the SQLite Manger for Firefox on the Mac and was able to point to the DB in the simulator directory and look at all my tables with ease. On the Android side I had to export the DB from the device to a temp directory and use SQLite Database Browser to see the table contents. 
  • Releasing to the clients is a huge win for Android. I can just put it on any device I want. I can submit it to Market and have it available in minutes and the same for updates. For the iPhone I can submit it and wait until Apple approves it. I can not give our clients a solid date as to when that will happen. Same thing for bug fixes. This means our Beta cycle will be pretty simple on the Android and a royal pain on the iPhone. Our clients are not local, I can't just have them stop by for new version. Doing it ad hoc might be possible if we can get a doctor to understand iTunes and how to drag and drop things I send them along with getting their unique phone ID to me so I can provision it and build it into the app. This is a gigantic pain.
No matter which device I was programming against I spent a lot of time in Stack Overflow looking for answers. As I have gone back to the iPhone side to do some program tweaks and add missing features I put into the Android side I again realize how much Objective C and I don't think alike. I still have to look up method names as they just don't roll off my brain. Trying to think how many staring '[' I need before I get to type code just seems silly. Having to type multiple lines to do simple things gets old.

I really don't care for Xcode, I really want tabs that keep open the code I am looking at instead of reusing themselves as they see fit.

Even though I was used to it with C/C++ I really don't like having two files for every object - the H and M files. I just want to add a method and have it there to use instead of adding it twice. Then you have the fun of static variables you want others to access which is tons of lines of code.

It will be interesting to see how the users respond to the application. Will any switch between devices and will they spot differences they don't like between them?

The application is used by anesthesiologist to do charge capture and billing. You have to be a client of ours for it to be of any use to you. All you could see without that access is our login screen so I can't give a link the program for anyone else to give me feedback on why I am insane to prefer Android over iPhone or to tell me where I totally hosed up doing something on either platform.

2 comments:

  1. As an iOS developer just starting with Android development I find this a very interesting read. I do have a couple of questions/remarks.
    1- Why weren't you able to set the visibility of iOS buttons? They are just views and all views have a visibility property.
    2- Why didn't you care to implement the animated transition on Android? I know on iOS it's dead simple to add animation, thanks to the Core Animation framework, and that the fact it's executed on the graphics card makes it look really smooth.Is there any animation support on Android? How about hardware accelerated animation?
    3- Why didn't you use a GCD queue for the async background activity? The point of an async background task is that the UI doesn't need to block, so why shut down the UI?
    4- Tip: you don't need to add starting '['s beforehand. Xcode will do that for you when you type the closing ']'.
    5- Why didn't you use a http client library instead of writing the multi-part http code yourself. There are myriads of http client libraries in C (and probably there are Objective-C wrappers for some of them):
    http://curl.haxx.se/libcurl/competitors.html
    6- "It will be interesting to see how the users respond to the application. Will any switch between devices and will they spot differences they don't like between them?" A little while ago I read an article where the main question posed was "Why do Android versions of the same app always look cheaper?". This article gave a list of example apps, of which I can only remember the Angry Birds app. Unfortunately the app didn't really answer the question. Have you got any clues?

    ReplyDelete
  2. Rudi, excellent questions

    1. You can set visibility of regular buttons but not buttons in a toolbar. A UIBarButton does not have a visibility setting.

    2. On the Android when you change orientations it loads the proper layout for you. Don't know if you can even catch something to do animations during the rotation. Very minor feature at any rate as most will never rotate the phone during program usage. Maybe just once and it would have to be on my home screen to make any difference. I tossed in the code on the iPhone as it was easy. I bet only 1% of iPhone users will ever see it.

    3. I can't have them doing anything on the screen like pressing another row in the table etc. while I am doing the background work. I am making server requests for data to show on the next screen or doing filter requests against the data on the current screen. The program is busy and I don't want you doing anything else at that point, you triggered and event and must wait for the results.

    4. I know Xcode will finish off [ ] pairs for you but it does not always do them in the correct place especially if you are also type casting a value. I let it complete them at times but I do it manually in other places so it does not break the syntax.

    5. I was unable to find an HTTP library that did what I wanted. I did a bunch of searches on multipart entity for Objective C / iOS and did not find what I needed. What I wrote was just to handle that one aspect of HTML. I guess I made it sound more dramatic than it actually was. I will check out the lib you suggested.

    6. Since you have a fixed resolution on the iPhone you don't have to worry about scaling your background. I have a shelf I am using to "set" my home screen icons on. I was able to use a nice diamond plate look there as I know I have one size for portrait and one for landscape. I created two images with the shelf at the proper width. On the Android side I am using a nine-patch image for the shelf. I was not able to do diamond plating as the corners would not line up with the expandable area. The code is more generic and works on phones and tablets but it is not as pretty. I find a lot more hard codes examples for iOS than for Android due to this. I have some hard coded values in my iOS code to calculate things based on known heights of status lines etc. Not happy about it but did not find a way around it either. I don't have hard coded values in my Android code.

    I also think Mac developers tend to have a better eye for visuals. The Mac leans that way in general more than windows. The users and developers care more. There are not many reasons for the two to be different especially if you are porting an application and have a Graphics Artist on hand to help out. Sadly I have to do all this work myself. Just getting the code done is hard enough without doing all the graphics too. I wish both platforms looked better.

    ReplyDelete