Monday, March 24, 2014

Android App Updated with Top Feature Requests

Today GQueues released a significant update to its Android app packed with users' most highly-requested features and improvements. The new version includes a quick view widget for the homescreen and lockscreen, adjustable font-size for tasks, a DashClock extension, homescreen shortcuts, and Google Now integration.

Watch the video below for highlights of all the new additions.


People who have auto-update enabled most likely already have the new version. Everyone else can install the update or download the app from Google Play now.

Don't have a GQueues subscription? Everyone can try out the new version of the app for two weeks free (even if a free trial has been used in the past).

A special thanks to the 40+ beta testers who discovered bugs and suggested changes over the past three weeks. Contributions from users help ensure the right changes and improvements are made to have the biggest impact for everyone!


Tuesday, January 21, 2014

Google Calendar Integration Upgrade Brings Speed Improvements to GQueues

Last November GQueues highly popular Google Calendar integration was completely re-written to use version 3 of the Google Calendar API. The upgrade was gradually rolled out to users in December, and hopefully you've noticed that queues load much faster now when you click on them. While the upgrade process was fairly seamless, quite a bit has changed behind the scenes to make these speed improvements possible.

GQueues 2-way syncing with Google Calendar has been a standout feature since 2009 when it was first added. To achieve this "real-time" 2-way syncing, whenever a person clicked to view a queue, GQueues checked the person's Google Calendar for any changes before displaying the tasks. This check increased the queue load-time 0.5 - 2 seconds depending on network congestion, but it was essential to providing the most current and accurate view of a person's tasks.

Last July Google added "push notifications" to the Calendar API. This was a significant improvement because it meant Google Calendar could be set to immediately notify a third-party server when any changes happened to a calendar instead of the server always having to check for changes. GQueues could finally be notified of calendar changes as they happened, and process them entirely in the background. The 2-second calendar check before a queue loaded could now be eliminated!

Unfortunately implementing the change was not so simple. The new "push notifications" feature is only available in version 3 of the Calendar API, which is wholly different than version 2 (which GQueues used), thus requiring a complete re-write of the calendar integration code. More troubling though, version 3 only supported OAuth2 for getting authorized access to a person's calendar. The Google Apps Marketplace did not support the newer OAuth2 protocol, so GQueues could not change to version 3 without leaving all its business users behind (obviously not a viable option). Fortunately Google updated the Marketplace in November to support OAuth2, and GQueues, as one of the launch partners finally had all the pieces in place to upgrade its calendar integration. After a few weeks of development and testing the upgrade was ready to launch and users now benefit from background calendar syncing and faster queue loading.

Tuesday, January 7, 2014

Top 3 Productivity Hacks for 2014

During the holidays I inevitably end up having conversations with family and friends comparing notes on the best apps we've found, how to do X on device Y, and savvy tricks we use to be more efficient and productive. It's always a great time of sharing and it prompted me to think about the tech "hacks" I use that have resulted in my largest productivity gains over the past few years.

Here are my top three "productivity hacks," which may seem commonplace to many, but they are so simple and provide such huge gains that they're worth mentioning for the benefit of anyone unacquainted.

1. Google Chrome Profiles to Manage Multiple Accounts

Most of us have multiple email accounts - at minimum personal and work - and often several more. I like to have all of my Gmail and Google Apps accounts open at once to save time logging in and out of each. Before 2013 I achieved this through a concoction of browsers - primary work email and browsing was isolated to Safari, all things personal in Chrome, test accounts in Firefox, and all secondary work accounts in a Chrome incognito window with Google's limited support for multiple account login. This configuration worked for the most part, but was a hassle to setup whenever I restarted my computer, and supported a limited number of accounts (I was still always signing in and out of test accounts on Firefox).

Profiles in Google Chrome changed everything!  When you add a profile to Chrome it's like running an entirely separate browser with a separate browsing history, separate cookies so your logged in accounts don't get mixed up and separate bookmarks.

Adding a profile to Chrome is easy - just go to Settings -> Users and "Add new user...". I created a profile for every email account I have, with a different color icon and theme for each so they are easily distinguishable. Now, essentially I have a separate browser for every account, and since I've signed in to Chrome once for each profile, I can open Gmail or any Google service without ever having to sign in again. (This also works great if you like to have multiple GQueues accounts open at once). And when I restart my machine I just select the profiles I want to open again and choose "Recent tabs" from the menu to restore everything as it was.

I can now open any email account with two clicks, keep all my online identities separate and open simultaneously, and I get to use my favorite browser for everything now too!

2. Multiple Desktops to Stay Organized and Focused

The idea behind multiple desktops is that you can create several different workspaces or desktops on a single computer, thus making it easier to organize and manage disparate computing activities and avoid having layers and layers of windows on top of each other. When I discovered how to setup multiple desktops several years ago it felt like I had just gotten 5 new computers for free!

Multiple desktops are available on most operating systems - Mac OS X allows you to setup "Spaces" for each desktop, on a Windows machine you can choose from a number of free applications to install, and on a Linux box they are included with most distros and desktop environments.


I have six Spaces setup on my Mac (you can add up to 16) - one for each type of activity with unique wallpapers for each desktop so I can instantly know where I am at. I've also setup keyboard shortcuts to quickly navigate between them (option key + the desktop number).

  • 1st desktop - All email accounts are open here, all social networking and web browsing happens here
  • 2nd desktop - All music apps are open here, the control center for my daily soundtrack
  • 3rd desktop - All web development happens here - Terminals, App Engine and testing on various browsers
  • 4th desktop - Exclusively for Photoshop
  • 5th desktop - Android and iOS development - Eclipse and XCode live here
  • 6th desktop - A "free" desktop for whenever I need a blank workspace

Using multiple desktops on my computer is the best hack for keeping myself organized and focused on the task at hand. When I start to develop a new feature for GQueues or fix a bug everything is already setup and ready to go on desktop 3. While developing, I'm less tempted to check my email every minute because it's not on the screen. If I need to design a new component, I hop over to desktop 4 where Photoshop is my entire focus. And when it is time to take a break and check email I can easily switch to this context without losing my place anywhere else. Yes, sometimes it's too easy to just pop over to desktop 1 for a quick peek. Having separate workspaces for each activity helps though, and with a little willpower I can stay focused on one task at a time, minimize switching costs and maintain flow while I work.

3. Multiple Monitors to Maximize Productivity

Adding an additional monitor to your computer setup is probably the easiest way to instantly increase your productivity. Increasing the size of your desktop allows you to have more windows open without covering each other, which means you spend less time switching between them. Copying text between documents or emails, referencing multiple articles, reviewing large spreadsheets all become faster and easier with an additional monitor.

There have been a number of studies and articles over the past 10 years showing productivity boosts from an additional monitor. I've actually cited these in two previous jobs to successfully lobby management for second monitors for all co-workers in my department. And with dwindling prices on monitors, it's even easier to get a return on this one-time investment.

Two years ago I updated my computer to a 15" laptop with a 27" external monitor. All my everyday activities were much easier with the additional desktop space, and my time at the computer was actually more pleasant. A year later I added another 27" monitor to my setup. Before purchasing, I thought it was a little excessive, but now I couldn't imagine working without it. Developing the Android and iOS apps for GQueues was so much easier having an entire screen for writing code, a second one for monitoring logs and debugging, and a third for simulators and documentation. Having multiple email accounts open and fully visible simultaneously is incredibly useful. And this hack is not just for developers - I know a number of accountants, managers, administrators and executive assistants who have all benefited from additional monitors.



Yes, some have questioned the validity of the second monitor studies, and it's true that in some cases people might become less focused when they have more things open and visible on their desktop. For me though, when I combine additional monitors with my multiple desktops hack I get the optimal setup. Each desktop encompasses all three monitors, so I have a huge amount of space within each desktop to maximize my efficiency, while still using distinct workspaces to maintain my focus.

There is certainly an abundance of tips for increasing productivity, but these three I found to have the biggest impact in my own work. What strategies and "hacks" do you use to help boost productivity?

Tuesday, December 17, 2013

OAuth2 Login Simplifies GQueues Access for Google Apps Users

When GQueues launched in January 2009 it was one of only a few sites that allowed users to sign in with their Gmail credentials. 11 months later GQueues expanded support to Google Apps users by offering a second login mechanism that used the OpenID protocol (a technology that was only beginning to gain widespread adoption). Having two login buttons was less than ideal, but OpenID was critical to GQueues' growth as a product, allowing business users to take full advantage of GQueues' powerful integration with Google services.

Continuing GQueues' pursuit of powerful simplicity, this past weekend GQueues switched to a single login mechanism powered by the newer, more robust and secure OAuth2 protocol. Now everyone can sign in to GQueues with the same button whether they have a Gmail or Google Apps account.





Tuesday, November 19, 2013

New Payment Options Added

Today GQueues has introduced new payment options to simplify the process of purchasing a subscription to the task management service. Users can now choose to pay directly with a credit card or use their PayPal account, and are no longer required to use Google Wallet.
From the beginning GQueues has been focused on providing a very intuitive experience within the app, and it's extending this to the payment process as well. Allowing users to pay directly with a credit card now eliminates the hassle of companies having to activate Google Wallet for their Google Apps domain, and individuals having to setup Wallet accounts. People who already have a PayPal account can choose this as their payment option and avoid having to type in their billing info. With both payment options GQueues continues to provide industry-standard 128-bit encryption over a secure connection ensuring your payment transaction is safe and protected.


Monday, October 28, 2013

Create Powerful Saved Searches in GQueues

Two weeks ago GQueues added full text searching of tasks - one of the most requested features from the GQueues community.  While the search box makes it easy to quickly find any task, saved searches give you a powerful way to filter and organize your work for retrieval at any time.

Many users often ask how to see a specific set of tasks, such as "everything I completed yesterday," "tasks due next week", or "all tasks with notes."  Custom Smart Queues can be created to show many of these sets, but some are not possible with the available options. Now with Advanced Search you have the power to filter tasks on a much wider variety of criteria and can save searches as Smart Queues for quick access later.

You can search for tasks based on specific criteria using the Advanced Search panel, and then click save search to make it a Smart Queue.

The Advanced Search panel is very intuitive, but some searches can only be expressed using the GQueues query language, which is easy to learn with a few examples.  For instance, to view all tasks completed in September type this into the search box:
Once you've tested and fine-tuned your search criteria, open the Advanced Search panel by clicking the arrow on the right, and then click save search at the bottom.
Give it a name and click Save to create a Smart Queue with this search.

Below are some more searches using the query language which you can copy and modify as needed to use in your own account.

Completed today

Completed in the last 7 days

Created today

Due in November

Tagged, but no due date

Without a certain tag

With 2 or more tags

With this tag, but not that tag

Either of these tags, but not that tag

With no tags

Not assigned to anyone

Without notes

Are there other searches you use or would like to know how to setup? Share them in the comments.


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.