Monday, July 29, 2013

Android vs. iOS: Comparing the Development Process of the GQueues Mobile Apps

A quick search for "android vs. ios" will turn up many articles arguing the benefits of one platform over the other, with most focusing on points such as market share, usability and device fragmentation. There are some posts that offer the "developer's perspective" on the platforms, but very few provide in-depth technical comparisons for anything more than basic features of a trivial app. And there's a reason for this lack of detailed comparisons: companies with sufficiently complex mobiles apps usually have one person or team building for Android, and a different person or team building for iOS. The two platforms use different programming languages (Java and Objective-C), have different software development kits (SDKs), and utilize different development tools, so it's no surprise that different human resources are used for each project as well.

GQueues is an online task manager, which previously only had an HTML5 mobile web app.  Recently I just finished developing both the GQueues app for Android and the GQueues app for iPhone & iPad. While these apps are not as complex as a first-person 3D shooter game, they certainly would not be considered trivial - storing and managing thousands of tasks for a user, supporting multiple accounts, providing background syncing to the web and offering complex filtering, sorting and grouping options. From this experience I hope to offer a fairly unique perspective analyzing and comparing the creation of the same GQueues app on both platforms.

STATS OVERVIEW

Android App
iOS App
Start Date Sept 21, 2012 Mar 2, 2013
Beta Ready for Testing Dec 22, 2012 June 10, 2013
App Published Jan 31, 2013 July 18, 2013
Total Project Time 4.25 months 4.5 months
Ramp Up Time 1 week 2 weeks
Development Time 870 hours (approx) 960 hours (approx)
Beta Testing & Fixing 34 days 38 days
Number of Beta Testers 92 people 48 people
Lines of Code 26,981 lines 23,872 lines
App Download Size 1.1 MB 3.5 MB
Video Overview GQueues for Android Video GQueues for iOS Video
Download Android app on Google Play Download on the App Store

GETTING STARTED

Learning Curve

I have 12 years of experience as a software engineer, but this was my first time making an Android app, and my first data-focused iOS app (I made two games for iOS 3 back in 2010, but they mostly dealt with animations and Bluetooth connectivity). The last time I wrote any significant Java code was in grad school classes, and my Objective-C coding was limited to the two games. So I basically started with an equal blank slate on both platforms.

In short, I was able to pick up Android development twice as fast as iOS. With Android I spent a week reading books, following tutorials and creating test apps that implemented all the core functionality that would be required for the GQueues app. After that I had the foundation to start architecting the app and wrote my first lines of code for the project. Within another week I was comfortably developing on Android without having to rely on a resource to implement each new feature.

With iOS, I followed the same process, but it took two weeks of experimentation before I felt ready to start the initial app code base. Much of this time was spent exploring all the intricacies of the Core Data APIs. Figuring out how to setup and centrally manage PersistentStoreCoordinators and ManagedObjectContexts for each user in a thread-safe manner took some work, but was critical to supporting multiple accounts within the app (and probably worth a separate blog post of its own). Even more time consuming was developing a scalable architecture for the FetchedResultsControllers that backed the tables of tasks, queues and categories that users would view and manipulate. Another 2 weeks of development passed before I was comfortably coding on iOS.

Overall, the quality of the Android documentation corpus (official docs, third-party tutorials, books, code samples, StackOverflow posts) is much higher in my opinion. I gleaned many architectural best practices from reputable open-source Android apps, such as the 2012 Google I/O app, which Google graciously made available to developers. Moreover, the Android platform itself is open-source, so I was able to dive into the platform code when necessary to figure out particularly troubling issues. While there is a proliferation of iOS documentation, much of it has become outdated with the significant changes made in iOS 5 and 6, including the introduction of Automatic Reference Counting (ARC). Thus, many code samples (including Apple's official samples) and ways to approach problems are inaccurate and should actually be ignored in favor of newer methods. Sifting through it all just took more time.

As shown in the Stats Overview above, developing the Android app was about 10% faster than the iOS app, even though as part of the Android app development I re-wrote the entire syncing code for the backend servers that was previously used with the HTML5 mobile web app. Creating an app that eschewed the generic, antiquated interface provided by iOS 6 added additional time, but even considering that, Android development just moved faster.

Resources Used
Android App
iOS App

The usefulness of the books in the lists above was limited, because, as is with all tech books, their content was somewhat outdated and for the most part only dealt with introductory level concepts. However, plowing through them in a couple days at the beginning of the projects was a fairly quick way to digest core functionality. Online resources were by far the most valuable for both projects.

Tooling

I'll share just a few comments about the developments tools of each platform, as this topic already has a lot of coverage. I'm not a huge fan of either Eclipse or XCode - they both have strong and weak areas (and really I just prefer my Vim text editor). Search in Eclipse is ridiculously slow and cumbersome.  Documentation search in XCode Organizer is infuriatingly sluggish. Filtering by log tags in Eclipse (with the logcat integration in the Android plugin) is super useful. Code completion is really good in both IDEs.  Interface Builder in Xcode is useless (more on that later). XCode Instruments, however, are extremely useful in profiling, measuring and debugging. Google had not yet released Android Studio when I first developed the GQueues Android app, but I'm looking forward to testing it out as I make updates.

As far as testing code while you write it, the Android emulators are a complete waste of time (it's really a joke how slow they are). In my development cycle I always deployed to real Android devices for testing - it was much quicker. The iOS Simulator, on the other hand, is very fast and made the dev cycle much more efficient. For each new piece of code I would start my testing with the simulator and only switch to device testing once it was more fully formed.

With Android I had test devices on each version of Android the app supported (except Gingerbread), and then relied heavily on my beta testers to get decent device coverage later. Obviously with iOS this was much less of a concern and I just used the oldest and newest devices supported for testing.

Test Devices
Android App
iOS App
  • Samsung Infuse (Froyo 2.2)
  • Nexus S (ICS 4.0.3)
  • Galaxy Nexus (Jelly Bean 4.2) 
  • Samsung Galaxy Tab 10.1 (Honeycomb 3.2)
  • Nexus 7 (Jelly Bean 4.2)
  • iPhone 4 (iOS 6)
  • iPhone 5 (iOS 6)
  • iPad 2 (iOS 6)
  • iPad 4th generation (iOS 6)

DESIGN

Layout

A requirement of the GQueues app was that it work on phones and tablets of all sizes, with the layout optimized for the different form factors. With the myriad of devices running Android, it's no surprise that the Android platform has mature components to help developers support the variety of dimensions. RelativeLayouts, which provide the ability to position one view in relation to another, have been available since the first version of Android and are key to creating flexible, responsive layouts. Additionally, with Android, all layouts are specified in XML, which is actually a very clean, simple and efficient way to design screens - a feature I only fully appreciated after creating layouts in iOS.

Auto Layout, Apple's analog to RelativeLayouts, is quite new (introduced in iOS 6) and its integration with Interface Builder (IB) is horrendous. I spent days fighting Auto Layout in IB, as has every iOS 6 developer, building precise constraints for views only to have IB completely change all my specifications because of its "smart" system to constantly maintain unambiguous layouts. I learned all the tips and tricks to deal with this fragile part of IB to no avail. I finally ended the pain by taking all layouts out of IB and simple wrote them long-hand with pages of boiler-plate code. If you avoid IB and Apple's geeked-out ASCII art style of layout coding, the implementation of Auto Layout is actually very powerful and straightforward to use.  Supposedly Apple has improved much of this with iOS 7, but I have yet to test it out.

When an app must be optimized for both small and large devices, the key to success is dynamic composition of views based on available screen real estate - known as an "Adaptive Layout." Tablets may display two or three views all on one screen, whereas a phone may only show one view at a time. Android supports this design technique through the use of Fragments, which are independent, self-contained modules that can be dropped into Activities as needed. By utilizing Fragments it was very easy to setup different layouts for GQueues by adjusting a few lines of XML for various screen sizes. To me, fragments were a very natural solution because they were modeled after the well-known Object-Oriented principles of high cohesion and loose coupling.
iOS supports the use of multiple ViewControllers on a screen through Custom Container View Controllers (you can also use a Master-Detail template, but the widths are static and customization prohibited). I found Apple's documentation of this nascent feature convoluted and incomplete, with the best resources being Ray's iOS 5 tutorials and the WWDC videos. After more work than seemed necessary I was able to architect GQueues layouts to present multiple views simulatenously for the iPad and only a single view for the iPhone.

Rotation

Suffice it to say, supporting device rotation on Android takes a huge amount a work and is the source of many bugs, whereas iOS requires just a pinch of effort while the platform does the rest. With Android, when you rotate a device it essentially terminates the entire stack of views and recreates each one when rotation completes. So to support rotation with the GQueues app I needed to ensure the current state of everything could be properly saved at anytime and restored on resume. With iOS, the platform manages almost all rotation concerns for you. The only real issue I had to worry about after rotation was adjusting the position of any views that weren't fully handled by auto layout.

"Complex" Layouts

There are a couple very common layouts on the web that were extremely difficult to implement for the GQueues app on both Android and iOS. One example I'll mention was displaying tags on the task details screen. Each tag is a variable width and the tags should wrap to the next line when necessary.  On the web this is achieved easily by setting the float value in CSS. Neither Android or iOS support this "Flow Layout" natively - which meant I had to add a lot of code to manually calculate and position tags to achieve this "flow" appearance. The Android code I ended up writing was based on the talk by Romain Guy and the open source flow layout by Artem Votincev. On iOS I took a similar approach using the total container width and making calculations for each tag to set the auto layout parameters as necessary. In both cases the amount of work required was surprising.

Older Devices

A common complaint about the Android ecosystem is extreme fragmentation. Carriers are very slow to push out updates, so there are huge cohorts of devices running older versions of Android, which in turn means developers must refrain from using the latest features of the OS if they want broad device coverage. However, I found the Android community has made great strides in addressing this issue by providing libraries that back-port many of the newest features. By using Android's official Support Library and Jake Wharton's ActionBarSherlock library I was able to use nearly every feature desired in Jelly Bean (4.2) while still supporting devices running Android 2.2.

With iOS, support for older versions of the OS is pretty much non-existent, though not nearly as crucial. In my planning stages I did spend a fair amount of time considering which versions of iOS I would support. While 83% of devices were reportedly running iOS 6 at the time, I had concerns about excluding owners of the original iPad, particularly because my parents and sister - hard-core GQueues users - all had the device. Ultimately I decided to only support iOS 6+ so that I could use Auto Layout exclusively without having to implement any of the deprecated layout techniques, which would have increased development time significantly. I solved the original iPad dilemma (at least for my family), by giving them 4th generation iPads to replace their antiquated devices :)

ARCHITECTURE

Data Storage & Management

At the heart of both GQueues mobile apps is the data - storing it on the device and syncing it with the web. The Android and iOS platforms have very disparate systems for managing data. Android offers ContentProviders, which are subclassable interfaces that sit on top of SQLite databases and act as structured frameworks for all the app's data needs. ContentProviders have a high learning curve and it required a lot of upfront work to get one running for GQueues. Once setup though, it was easy to expand and customize as I built out the full data model.

As background info, the GQueues web service is backed by Google App Engine's Datastore, which is a highly scalable and distributed NoSQL data storage system.  SQLite, on the other hand, is a standard relational database, which obviously doesn't scale very well, but that's irrelevant for the app since it's only storing a single user's data. (As an aside, I made the architectural decision to create separate databases for each user, which was paramount to providing quick and simple support for multiple accounts in the app, but the implementation details deserve a post of their own).  Anyway, a huge advantage with Android was the ability to create SQLite Views to back Smart Queues. Figuring out the very complex table joins and subqueries needed to support Smart Queues took some work, but enabled more efficiency and faster loading of Smart Queues since the filtering was not happening in the code.

With the iOS app I used Core Data, which is the platform's "schema-driven object graph management and persistence framework."  Essentially it can be thought of as a NoSQL datastore, although interestingly, it is in fact backed by a SQLite database (well, that was the most reasonable choice of several options).  iOS does allow users to create SQLite databases directly, but it's all done with regular C code and lacks built-in integration with other iOS components.  Core Data also has a high learning curve, but ultimately I chose it over a standard SQLite database because you get so much functionality "for free" - including caching, data model migration support and the use of a NSFetchedResultsController, which makes providing data for the tables in the user interface much easier.

A key to managing any dataset, of course, but particularly vital with syncing, is the use of transactions - atomic, consistent, isolated, durable units of work (ACID).  On Android transactions were very straightforward and implemented the same way as most relational databases management systems, thus, maintaining data integrity was not too difficult. Plus, by strategically taking advantage of SQLite's support for UNIQUE ON CONFLICT REPLACE clauses with certain columns during table creation, updating records atomically during the sync process required virtually no work at all.

Transactions with Core Data (an in-memory object graph) are not fully supported in the strictest sense.  By using separate child ManagedObjectContexts for background thread processing (thread confinement) along with strategic placement of @synchronized blocks I was able to implement proper handling of data updates and syncing while avoiding incorrect overwriting. iOS's suggestion for efficiently updating or creating objects was only marginally helpful, and overall I found using Core Data cumbersome despite its purported advantages.  Additionally, whereas SQLite in Android enabled fast loading Smart Queues, in the iOS app all filtering had to be performed in code, which is slower even with the use of extensive caching.

Search

Adding fairly robust full text search capabilities to the Android app was simple.  I modeled my implementation after search in the Google I/O app, using the FTS3 feature of SQLite to create a virtual table populated by several triggers set on the table that stored a user's tasks.  From there it was just a matter of designing the search interface and adding storage for search history.

Core Data in iOS does not support full text search natively, so I chose to implement basic search functionality through the use of LIKE clauses in a predicate for task descriptions and notes.  It is certainly not as powerful as full text search, but I reasoned it still covered a large percentage of real life use cases.

Feature APIs

I'll only mention a few APIs that I used in building various features of the GQueues apps for comparison purposes.

Quick Add
Regular Expressions were critical for implementing the Quick Add parsing in GQueues and fortunately both Android and iOS provided RegEx support natively.  Android's Pattern and Matcher APIs have been available since version 1 and include support for a fairly extensive set of regular expression syntax including look-ahead and look-behind assertions.  iOS introduced the NSRegularExpression class in iOS 4, and I was happy to discover that my pain-stakingly crafted expressions in Android could be used almost verbatim in iOS.

Paging
In designing the app's interface I wanted the user to be able to swipe between pages of task details.  In Android I used a ViewPager along with the fledgling FragmentStatePagerAdapter, which is truly in the experimental stage and only available through the Support Library.  I spent several days getting an initial implementation hooked up to the data, and several more fighting bugs related to duplicate menu options and proper handling when the data changes.  This was all way more difficult than I expected and I would have left this out of the app except that swiping through tasks is such a great user experience. The UIPageViewController on iOS was significantly easier to use, though it still had several quirks I had to work through, and adding my own caching system was necessary to make swiping between the complicated views actually usable.

Voice Input
Android provides a state of the art speech-to-text API that is very easy to use. With 20 lines of code I was able to integrate the RecognizerIntent into GQueues and provide a customized voice input feature.  Unfortunately, iOS has yet to provide an API for the tech behind SIRI, so developers are left to use third-party libraries or rely on the keyboard's microphone option for voice input. I surveyed a variety of third-party options, including Nuance (the provider of voice recognition for SIRI), but found the free libraries lacking and the paid services cost-prohibitive.  So ultimately the GQueues app relies on people using the built-in keyboard microphone option, which is quite adequate, as long as users remember it's there.

Sharing / Widgets
Through the use of Intents Android makes it simple to integrate your app into others installed on a person's device. Again, with a small amount of code I was able to allow people to create GQueues tasks from inside other apps by supporting the ACTION_SEND intent.  Android also obviously provides a full widget platform and I built a few initial widgets, with plans to add more in future updates.  iOS is clearly behind in the areas of cross-app integration and home screen widgets, completely lacking support for both features.

TESTING AND PUBLISHING

Beta Testing

As noted in the Stats Overview, I beta tested both apps with real users for a little over a month.   The testing volunteers in both groups were fantastic, helping uncover dozens of bugs, providing suggestions for additional features and offering feedback on user-interface elements that weren't quite right.  The beta program, which I managed with private Google Groups, also helped me ensure that I was launching apps that would truly be useful to people.  Near the end of each beta period I gathered more structured feedback through a survey which helped me judge if the apps were ready to launch.

On-boarding Android testers was as easy as posting a link to an APK which they could download to their device (well, they also had to flip a switch in Settings to allow installs of apps not on Google Play).  Google has made it even easier now to test apps with real users by supporting alpha and beta versions in the Developers Console and staged rollouts.  I'm looking forward to using both features as I launch updates to the Android app.

iOS beta testing was much harder, despite using the service TestFlight, which does simplify the process a great deal.  In keeping with Apple's insatiable appetite for control, the UDID of every device used for testing must be added to the certificate used to sign the beta version of the app.  Consequently, every time I needed to add beta testers, whether a single person or a new cohort, I had to create and distribute a new build of the app.  On top of that, Apple limits you to 100 registered test devices per year, so I had to carefully allocate my spots, which is the reason I had half as many iOS testers as Android.

Publishing

Of course no Android / iOS comparison would be complete without mentioning the publishing process.  Posting the GQueues app on Google Play was a real joy.  I was able to launch the app as soon as I decided it was ready. I clicked the button and within 30 minutes it was available on Google Play worldwide and customers were installing it on their devices.  Publishing on the App Store, as almost every iOS developer can attest, is a demoralizing experience.  After months of intense, rigorous coding, I was forced to submit my creation to Apple and wait 7 days at which point the reviewer spent 2 minutes looking at the app before giving the almost obligatory initial rejection.  I then spent a day making required changes and submitted again so I could wait another 8 days before finally getting approved.  Of course there are many truly horrific App Store submission stories out there which make my experience seem like a walk in the park.  Regardless though, I felt very anxious and uncomfortable relinquishing so much control over my business to such a temperamental third-party.

THE WINNING PLATFORM

As you can see from my analysis above, in my experience building the GQueues mobile apps, one platform does not clearly outshine the other.  Both Android and iOS have areas where they are really strong and mature, and other aspects that definitely need some improvement.  Looking at the history of both platforms, it seems like Android may currently have more momentum, not only in terms of marketshare, but considering the huge improvements to their UI in the last two years and steady enhancements to their development platform.  Apple though is the king of secrecy and I'm sure they are hard at work building what they believe to be the next revolution in mobile computing (besides finally killing off skeuomorphism).  In either case, when I think about the emergence of the app eco-system in the last 6 years, I feel fortunate to be able to develop on these platforms during this time of such rapid advances in mobile technology.

47 comments:

  1. Two things in regards to iOS that you are incorrect about:

    iOS has the ability to register an app for a URL scheme that other apps can query for and call, thus allowing for cross-app integration. Here's a good index: http://handleopenurl.com/

    Test Flight allows you to upload a new provisioning profile to an existing build, thus allowing you to "add new beta testers" without redoing and submitting an entirely new build.

    Good write-up though!

    ReplyDelete
    Replies
    1. Thanks for the corrections, RWyland! I'll have to try the provisioning profile upload again in TestFlight for my next update (I could never get that to work on its own during the first beta testing period).

      Delete
    2. Registering for URI schemes is a far cry from the intent system and what was being referred to here for the purposes of sharing.

      Delete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
    Replies
    1. Man, this is serious blogspam you're doing here. Please refrain from polluting this comment section like this. I hope the author flags you.

      Delete
  3. Shame this isn't a paid app as I suspect the revenues would be towards iOS.

    ReplyDelete
  4. If documentation search in Xcode is very slow, you might be searching all documentation sets (the default) instead of just the iOS/C/ObjectiveC sets (much faster, in my experience). I think the UI to fix this is really obscure.

    To change the options, get to the search box* then see the little magnifying class in the box. It has a tiny down arrow next to it, which apparently implies it's clickable. When you click it you get search options, including a "Find in" box that specifies which docsets to search. For native iOS development I just have the Xcode and iOS 6.1 docsets checked, so 2 sets out of about 7. I've found searches to be much faster after making this change.

    * Go to Organizer/Documentation and click on the magnifying class in the left panel, or [Shift]+[Cmd]+[Option]+[?] from anywhere in Xcode.

    ReplyDelete
    Replies
    1. Ah, yes, this actually sped things up a bunch. Thanks for the tip, Tom!

      Delete
  5. Very interesting article, as a iOS dev it entices me to take a close look at Android.

    One comment : you could have used a UICollectionView with a UICollectionViewFlowLayout for your tag list.

    ReplyDelete
  6. For the Android simulator: There used to be a difference in speed like day and night depending if you are on Mac Osx or Linux.

    ReplyDelete
    Replies
    1. Intel has something that could speed it up, except if you're using Google Maps. If so, you're F...

      I had te make a Android prototype at work and didn't had a real device. I almost killed myself! :-)

      http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager

      Delete
  7. The Android ARM emulator is slow, the x86 one from Intel isn't, however.

    At least that's my experience.

    ReplyDelete
  8. Android Studio (or even IntelliJ IDEA) is an order of magnitude better than Ecipse, in my opinion.

    Regarding slow emulators, you might want to check out Genymotion (http://www.genymotion.com/)

    ReplyDelete
    Replies
    1. And AppCode (from the same guys) is an order of magnitude better than Xcode.

      Delete
    2. I really want to like AppCode, and it definitely has many advantages, but there are two things that keep me on Xcode. First, the fact that Xcode is still needed for Core Data and Interface Builder. I use those two tools quite a bit for my app, and the assistant editor is practically a requirement for that workflow, so I really dislike needing to switch between the two for those tasks. And the second thing is actually vim. When I was trying AppCode I was using the IdeaVIM plugin, and it is ok, but the lack of a .vimrc and other limitations made it feel like a chore to use, especially after using an XCode vim plugin called XVim. XVim is a surprisingly complete vim plugin, it doesn't support all of vims more advanced features like scripting, but many of the keyboard shortcuts are there, .xvimrc files are supported for keyboard configurations (I love using jk to leave insert mode and I couldn't do that with IdeaVIM but with XVim I can), and there is also pretty good integration with other XCode features.

      Delete
  9. Having written multiple apps for both iOS and Android I found this to be a very balanced review. I decided to go straight SQLite on both sides allowing easier code ports. I did give Core Data a shot on my last app but I was doing a lot of bulk imports from large JSON requests and it was just too slow for that.

    I did find your solution to iOS fragmentation to be amusing. Since your parents could not run your app you gave them new devices! Of course I have run into situations where family members could not run an Android app (not written by me) so I helped them root and update to a newer version allowing them to do what they wanted.

    As mentioned by others the base Android emulator stinks. Genymotion and the HAXM Intel work great though. Genymotion only emulates newer Android version where HAXM can be used for older Android versions. I use them both.

    I need to get into AutoLayout on iOS. Have not used it yet as I could not ignore older devices. I wish the syntax was more along the lines of MigLayout which I use for Java desktop work. I find the Android layout managers to be very flexible and make it very easy to deal with landscape vs. portrait. Of course you have to deal with the Activity life cycle which can be very annoying.

    For the projects I have written I have found the Android code size, not line count, to be nearly 1/2 the size of the iOS code size. You listed line counts only. For Android I use .JAVA + .XML and for iOS I use .M + .H to determine code size. Objective C + iOS Framework is very verbose. Curious what you code size in bytes happens to be.

    I found Xcode to be more limiting than Eclipse especially when it came to refactoring code. Xcode could not even refactor an enumeration. I ended up using AppCode from IntelliJ to get around those limitations.

    Generally I could find a solution or at least a heck of a start to an Android issue on my first web search. It generally took 3 web searches to find iOS solutions. My mind does not think using the same terms as the NextStep folks. Android does start / stop on a timer. iOS is start and invalidate. Huh? Trim a string is trim() in Android and 100+ character long line in Objective C. For iOS simple things just took a lot longer to discover solutions for which greatly cut into my programming productivity.

    ReplyDelete
  10. Checkout http://www.genymotion.com/ it's using Virtualbox to provide super fast Android emulator.

    ReplyDelete
    Replies
    1. I'll definitely have to check out some of the other emulator options - thanks for the suggestions, Bojan and Ben!

      Delete
  11. As for the XCode documentation whoes, you could try using Dash. Its search is very fast, has hotkeys and it has docsets for several languages/frameworks (https://itunes.apple.com/us/app/dash-docs-snippets/id458034879?mt=12)

    CoreData is really a beast and there's too much boilerplate. To improve that, you could consider MagicalRecord (https://github.com/magicalpanda/MagicalRecord). It really improves the experience.

    ReplyDelete
  12. Cameron, as the author of More iOS Development, and currently working on the update, I'd like to get your feedback on what I could have done better. Email me at kevin.kim at apporchard.com - Thanks.

    ReplyDelete
    Replies
    1. Kevin - Thanks for writing More iOS 6 Development! I found it very helpful in getting my bearings with Core Data, which is such a huge feature to fully learn. I emailed you my thoughts on how to improve the next edition. I'm glad there are experts in the field like you who are willing to share with those of us new to the platform.

      Delete
  13. Always nice to see balanced reviews. Tip: on Android there is an attribute you can set on the Activity if you don't want orientation change to recreate the UI. http://developer.android.com/guide/topics/resources/runtime-changes.html

    ReplyDelete
  14. Maybe you could have used Phonegap and jQuery Mobile to develop both versions at once? Though the structure of mobile web apps is maybe a little bit of a departure from what native app developers are used to.

    ReplyDelete
    Replies
    1. Kraig - I actually built an HTML5 mobile web app for GQueues back in 2011, with the idea that I would only have to maintain one mobile codebase. Unfortunately, the mobile web app just didn't cut it for my users, or my business.

      See here for why I finally decided to build the native apps:
      http://blog.gqueues.com/2013/02/eating-my-own-words-gqueues-switches.html

      Delete
  15. Your comparison is very objective, so what's your subjective view? Which platform did you have more fun coding on? Or if you have a smaller app idea, which platform will you build and publish on first?

    ReplyDelete
  16. Good article. Haven't made it all the way through yet, but I would like to point out a possible typo of omission:

    Layout section, paragraph 2:

    "If you avoid IB and Apple's geeked-out ASCII art style of layout coding, the implementation of Auto Layout is actually very powerful and straightforward to use."

    Did you mean to say: If you avoid IB and INSTEAD USE Apple's geeked-out..."?

    ReplyDelete
    Replies
    1. Aijaz - I actually avoided the ASCII art style of coding as well. It just seemed like a hack they added to make auto-layout seem more cool, and possibly more succinct, at the cost of clarity. Perhaps I'm just too old school, but I wrote my constraints using the plain old constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant method. This also allowed me to easily keep a reference to certain constraints, so they could be easily adjusted at other times, such as after rotation, or when they keyboard is displayed.

      http://developer.apple.com/library/ios/#documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html

      Delete
    2. Got it. Thanks for clarifying that.

      Delete
  17. Hey Cameron, I'd be happy to hear more about the specific issues you ran into with ViewPager in your app to see what we might improve.

    ReplyDelete
    Replies
    1. Thanks for reaching out, Adam! I'll send a more detailed explanation over to you on Google+.

      Delete
    2. I had recently gone through this pain for 8tracks newest app (still being developed) so feel free to contact me too. as I've made extensive use of ViewPager and FragmentStatePagerAdapter.

      Delete
    3. Sure! I messaged you on Google+. I think it's great that Google's Android engineers such as Adam are so open to feedback from the community. Martin, I'm sure he'd welcome any input you have to share as well.

      Delete
  18. Great article, glad I found it.
    I've never developed an App before but as a ex Java, C++, Dot.Net and general frontend dev I thought I'd give it a crack but was a little concerned I was biting off more than I could chew.
    You have now giving me hope!

    ReplyDelete
  19. Great article, Cameron! So few people actually deal with things like rotation in their reviews and yet it is so important. One thing I would mention though is that the utter redraw on rotation is good to handle on Android anyway because of interrupt/resume handling in the OS anyway. So in that regard, as a tester, I use rotation all the time as a quick way to see how the developers are handling lifecycles in the UI.

    Another area that would be worth discussing, and again I'm a tester so this is near and dear to me, is continuous integration. With Xcode 5 and Mavericks Server, iOS has been brought MUCH closer to where Android is (though the tools are still in Beta). Even though JUnit owes its heritage to Apple, it has far outpaced OCUnit in terms of what each respective SDK provides. Once the new XCode 5 and Mavericks Server systems are officially released, I'd be interested in reading your impressions of their Continuous Integration system versus Android on Jenkins for example.

    ReplyDelete
    Replies
    1. A big reason why rotation works the way it does on Android is actually because this is the same path as re-creating an app from its saved start after it has been killed in the background. :) So if you are handling rotation correctly (without trying to play games), you have most if not everything also covered to correctly come up in the same state when the user returns to your app after it has been killed in the background. And all that annoying work you need to do for rotation to work correctly is at the bare minimum nothing more than you need to do to correctly restart.

      Delete
    2. Yes, you're absolutely right, Dianne! I neglected to mention that point in the comparison. As you said, the work to handle correctly restarting an app in Android and correctly handle rotation is the same. And to compare then, iOS didn't even have a concept of "resuming" an app until iOS 4 when it supported multi-tasking (fast app switching), and it didn't offer real built-in support for "resuming" until iOS 6 when it introduced the State Preservation and Restoration feature. So clearly iOS seems to be behind Android in this area.

      Delete
  20. Did you consider using a cross-platform SDK like Xamarin? I haven't used myself, but reports all seem promising, and certainly worth a look if you plan writing for multiple platforms.

    ReplyDelete
    Replies
    1. Hey Marcus -

      In 2011 I actually built an HTML5 mobile web app for GQueues with the idea of having only one mobile codebase. However, it just wasn't meeting the needs of my users. Several months ago I wrote a blog post on why I decided to switch to native apps.

      I considered using a cross-platform SDK for only a moment and concluded it wouldn't to solve any of the problems that were present in the HTML5 app. In my opinion, the only way to build apps that are truly designed and optimized for both Android and iOS is to build a native app on each respective platform.

      Delete
  21. If you wanted to use SQLite on iOS, why didn't you? Apps that are better suited towards it should use it; it *is* included, after all.

    ReplyDelete
  22. This is a great article. I've been developing iOS for several years now and have been resistant to trying Android development. Your write-up makes me feel that Android development may be more approachable than I had thought.

    ReplyDelete
  23. Great article. Do you think it is a good idea to learn both platform at the same time?

    ReplyDelete
    Replies
    1. For me learning one at a time worked well. The languages and SDKs are very different in terms of writing the actual code so living the Java/Android life for awhile and then shifting to the Objective-C/iOS life helped me keep everything straight. Now that I am comfortable on both platforms it's much easier to switch between the two and not waste time trying to remember the particular method names and parameters for the current platform I'm working on. But if you're adventurous and want to learn both simultaneously, then go for it!

      Delete
  24. Great article -- Very balanced... I'm an IOS dev working on Android and I am beginning to see what you talk about -- some thinks are trivial in Android that are a pain in IOS & vice versa.

    I do wish Android provided the deep tool integration that IOS support though....

    ReplyDelete
  25. Thanks for your article and had similar experience trying to find books (outdated). Being from the old school, java/android is new to me. Idot guide was hilarious ISBN 978-1-61564-1-062 by Penguin book since no source code as promise by Alpha or author on there site (lol, repository info by author for user support in coding help ) . New Boston videos by Travis was informative for the hands on approach to IDE(eclipse editor). Lynda video was not informative. OO/ class-object-method thinking made it necessary for me to read some books.

    What online site did you find informative for IOS? Looking for online tutorial and stack overflow is one of my resouces when I have a better understanding to ask a question. Exposure to C, a long time ago. Tx

    ReplyDelete
    Replies
    1. Anita - I found Ray Wenderlich's tutorials to be the most useful online resources for iOS. There are several tutorials for free to get started. I purchased the "books" (downloadable PDFs) and found them well worth the money.

      Delete