Sunday, May 30, 2010

Second Rejection of MultiPaaS Coupons iPhone app

We just received another application rejection. The first one was due to the use of an undocumented API, used to terminate the application cleanly. I can understand that one, even though they didn't give us a documented API to handle terminating the application in a standard way. Instead, they expect us to use exit()!

Anyway, so here is an excerpt from the e-mail we were sent:
Your application, MultiPaaS Coupons, cannot be submitted to the App Store because it uses a standard Recents button for an action which is not its intended purpose.


The first frustration is that they could have found this during the first pass! Why didn't they send me both problems at once if they were so worried about it? My guess is that they just have multiple people handling these applications and the first one didn't think it was a problem.

Anyway, this is my response:

I disagree with this assessment. There are two standard Tab Bar buttons that use the exact same image: Recent and History. The only difference between these two buttons is the words that are used. The only commonality between those two terms is that both are based on time (the icon itself is a very simple clock) and they happen to both be periods in the past (one recent, one further in the past).

MultiPaaS Coupons uses a similar image to these (again, a simple clock), but uses a different word, "Expiring". Again, the concept is temporal in nature so it should not be confusing to users. The only difference is that it represents a concept in the near future, i.e. "soon". Therefore, it is perfectly reasonable, according to the specification at least, to reuse the icons for the same purpose. The usage should be obvious because different words are used.

In the case of coupons, "Expiring Soon" means that these coupons are really important, similar to "Recent" items in other applications. Conceptually "Expiring" is more closely related to "Recent" than "History" is, yet "History" uses the same icon as "Recent". It should not be confusing to users to see an icon of a clock and think "oh, these are coupons that are important because of something based on time."

In fact, because the icon is a simple clock, anything temporal in nature is fair game from a user interface perspective. If the icon were more complex (such as a clock with some annotation indicating the past) then it would be appropriate to limit it in some way.

I completely agree with standards and not confusing the user, but let's not go overboard and reserve a simple iconic symbol like a "clock" to always mean "recent". Let's give our users a little more credit than that.

Regards,
Michael

P.S. Is this the only problem with the application? Or, are there other problems that you will find later? It would take much less actual time to get the application into the App Store if we could get more than one problem at a time. This is the second problem the team has found and it could have been found at the same time as the other one and therefore we could have had this conversation earlier while I was fixing the other issue. Thanks for understanding!


We'll see what they say about the response, and I'll work on another icon just in case, because whether it's fair or not, they have all the power, and they can choose to wield it at will.

Update 6/1: Got a nice call from Apple today about my iPhone app. The guy was really helpful, and he encouraged me to resubmit with new icons. Actually, I was impressed that they called at all, so I've resubmitted with all new icons. We'll see what happens next in the saga! Eventually I'll need to update my screenshots, but not tonight.

Monday, May 17, 2010

First iPhone App

I finished development on my first real iPhone app this weekend! The application is very simple and is an extension of our MultiPaaS Web Application. The first app is an iPhone version of Coupons. Here are my impressions of the process and development experience.

The coding itself took only about 100 to 120 hours of total time, or somewhere between 2-3 weeks of full-time work. That was spread over about a month and a half of real time, mostly during the evenings. Working that way makes things take longer because of the context switch involved to get back into the mindset of the code (not to mention the activation energy!) Also, since I hadn't built anything in Objective-C or Cocoa before, I was learning a couple of very interesting technologies at the time. Overall, I think it's pretty reasonable to be able to build an app for a platform in such a short amount of time, and it says a lot for the framework and support that's available.

Speaking of support, I bought a book on iPhone development to help me build this app, and it promptly sat on my bookshelf for the past couple of months. I just don't learn that well from books — I'd much rather get in and start coding. I'll probably use it for some nice leisurely bedtime reading, and then I'll learn some of the right ways to do things!

The resources I did end up using were all online. The iPhone Developer's Guideand the iPhone Dev Center in general helped immensely. Plus, Xcode has the entire set of documents for iPhone development built in — rather typical for an IDE — so I did most of my library learning through there. And Google, of course. Most of the time I would just search for the answers, and most of the time, somebody had done it before.

For example, I used a modified version of Matt Gallagher's OrderedDictionary in the code, which was very helpful. Yes, I could have written my own version, but his was pretty good and only required a bit of modification for my own purposes.

By far the easiest part of the application to build was the UI. Not just the UI display development using Interface Builder, but the UI* classes are pretty easy to understand. In contrast, the most interesting and challenging part was the interaction with the MultiPaaS web site. And, surprisingly, once I used it for a little while, Objective-C turned out to not be so bad. There were many parts that frustrated me, such as the bracket notation and the lack of true encapsulation, but overall it wasn't bad. After all, it's just another programming language, and they all have their warts.

To elaborate a bit on the interaction with MultiPaaS, there were a couple of parts that I needed to work with. First, MultiPaaS is built on Google Web Toolkit (GWT) for its browser-based view and all of the remote calls with the server. That remote protocol is rather complex and not something I really wanted to reproduce within iPhone. However, I wanted to be able to reuse the methods that were exposed. Therefore, I decided to change the base class for the RPC implementations to provide a REST-based API as well. This proved to work out really well, especially since I already had a generic method to generate and parse XML for Java objects. The worst part was reproducing the Java beans in the iPhone app — now I have two copies of the same classes. Then I needed a way to convert from XML to Objective-C classes, and that's not something I found on the internet.

In addition, I didn't want to call MultiPaaS for every UI interaction on the iPhone since that would degrade the user experience considerably. Instead, I wanted to cache all of the data locally. I chose Core Data for this so that I could query the data, update it quickly, and even allow the user to store new coupons within the application's cache. That was also easier than I expected.

After development was complete, it only took a couple of attempts to get it into the App Store. Into, mind you, not approved yet, though hopefully that process doesn't require too much effort. I had already had to go through the hurdle of getting into the App Dev program so that I could test the app on my iPhone, so getting a distribution certificate proved to be fairly painless.

Speaking of getting into the App Dev program, don't try to do so as a Sole Proprietorship. They won't take it, even with a Texas Retail license. In the end, since I don't want to pay for incorporation fees at the moment, I had to put everything under my name. When there's enough interest, we may incorporate, but until then, we've been down that road before, and it's not really fun.

Here are a few screenshots of the upcoming app:


I'll add a link when it's available on the app store.