As any iPhone application developer who’s released at least a single app to the App Store will tell you, releasing your app is a terrible pain in the…well, it’s not a fun experience. After your second or third app you start to get the hang of things, but there’s still pain and suffering involved. Managing certificates, getting settings configured properly, and iterating between development, AdHoc beta builds, and the final App Store release builds, all make the process seem tediously manual and prone to human error.
In professional software development shops, you would use a Continuous Integration server to monitor your source control repository, check out changes as they’re submitted, compile, test and package up builds, and notify developers of the build’s health via emails and a web-based “Dashboard”. I missed having this while developing my PhoneGap-based iPhone applications, so I decided to once and for all bring good development practices to my iPhone work.
Why do I need to configure automated builds anyway?
I get this a lot from people when I’m trying to convince them of the need for automated builds. I personally find it hard to imagine people getting by without them in a single-developer project, let alone when multiple developers contribute to a project.
Monitoring the health of an application
Lets face it, we’re human, and we make mistakes. It’s alright to break code from time to time, but what really sucks is when you find out far too late. Did your recent changes accidentally eliminate your Entitlements.plist file, thus breaking distribution or release builds? Do you have a file or library you forgot to check in, meaning when you delete the project from your working directory all those changes will just vanish?
Instead of having to remember to check each of those things manually (which, lets face it, you’ll forget at least half of the things you’re supposed to do inevitably), why not have an automated system tell you every time you make a change? And if you’re in a multi-developer project, you’ll be able to see who broke the build and what change specifically broke it.
Always be ready for distributing your application
Many times in the natural course of development you’ll break code. You’ve gotta break something in order to improve it. But sometimes someone (your wife, a client, a beta tester) will want to try out your application before you have an opportunity to finish off your recent changes. Instead of spending ages back-tracking your work to get your application to compile, why not rely on your automated build system to keep archives of previously successful builds?
Release what you test
Since you want to test an application before you release it to the App Store, you’ll probably create an Ad-Hoc distribution build to give to friends, family, or official beta testers before you bundle your application up to send to the App Store. Maybe your testers will find bugs, maybe they won’t. But at the end of the day that compiled app bundle you just created isn’t actually what you submit to Apple. You need to compile a completely different app bundle with very different files stored in a Zip file, and if you’re not careful you could potentially be releasing something different than what you tested.
Why not have your automated build system create both your Ad-Hoc distribution build as well as an App Store release build every time? That way you’re not only always ready to release something to the App Store, but you can be guaranteed that you’re submitting to Apple the exact code that your testers evaluated.
More benefits than I can list
If you’re really serious about best practices, you’ll probably want to write unit tests for your code and have those run after your code has been compiled, but before your build is packaged and archived. Just because your code compiles doesn’t mean that it will behave correctly. And lets face it, if you have a lot of tests, you’ll never wait for all of them to run throughout the course of your work. So by running your tests as a prerequisite to a build succeeding, you’re guaranteed that you’ve got a safety net.
There’s plenty of other best practices that having an automated build system can help with, so what I’m discussing here will just cover the tip of the iceberg. If I’ve convinced you that automating your builds, read on.
Things have been busy over the past few days, which is the reason why I haven’t had a chance to post about this until now. But for the PhoneGap community, I have some good news and some bad news. First, the good news: I got a phone call from the Apple app reviewer that was reviewing my test app. And before I go any further, I want to say a few things.
When I crafted my original letter to Apple, I was very cautious how I wrote it, because I don’t want to give anyone the wrong impression. I don’t have any problems with Apple or the fact that they have an app review process. I actually think the strict regulations Apple has with its review process is a good thing for users. If left to their own devices, app developers would release anything and everything whether it had merit or not, in the hopes of earning even a tiny bit of a buck.
That’s not to say that I have nothing but a big warm and fuzzy feeling for the review process, just that it’s like going to the dentist. It’s painful, but you’ll thank them later in life when your teeth would otherwise be falling out – or, in the case of the App Store review process, when the app store would otherwise be overrun with endless seas of buggy and non-functional crap.
Most developers out there seem to vilify the app reviewers, making them out to be legions of sadistic bureaucrats who like nothing more than to waste developer’s time. I’ve never been comfortable with that, because people simply don’t work that way. The app reviewers don’t have an easy job. They’re not developers, they don’t know how to write apps, they just review them to ensure they meet the guidelines Apple sets forth.
So when they reject your app, it’s not because they’re out to get you, they’re just enforcing policy. If they make some assumption about your app, perhaps you’re not giving enough information to help them along? There’s a comments field that you can use to help the reviewer of your app do their job, instead of throwing an app over the fence and saying “Here, take that”. They don’t owe you anything, and are simply making sure that they cover their asses. Could you imagine how bad it looked on the guy who reviewed the “Shaking Baby” app? I’m not sure if he lost his job, or just got seriously reprimanded, but this is the sort of thing these guys are trying to prevent. But because of the black-box nature of the whole process, it’s easy to jump to conclusions.
Finally, before I dig into the meat of my conversation with my App Store app reviewer, I want to point out a few things that many developers seem to have forgotten in their haste to get their apps released:
1. The app store is a voluntary process; you don’t want to play by their rules, you don’t have to.
2. All developers signed an agreement that states Apple can choose to reject any apps they want based on their own reasons. There’s no human right’s violations committed when Apple decides that your app isn’t fit for the store for some reason.
3. Apple is a business, whose goals are to advance their stock and market position for their investors. While some of Apple’s decisions may seem confusing from outside the black box, keep in mind that they are prone to keeping secrets until they throw down their big announcements at whatever annual conference they’re attending. So there are sometimes more reasons why they wouldn’t want some feature leveraged by app developers if they plan to do something much the same themselves. Is it fair? No. Is this what they’re doing? I have no idea, this is speculation on my part.
Now that I have that out of the way, I’d like to relate to you my conversation with Steve from the App Store.
I’ve made some quick updates on the train this morning, and ended up creating a Bourne shell script in the iPhone directory of PhoneGap for renaming a brand-new PhoneGap fork to whatever your project is called. This also works with the previous changes I made to my buildprocess branch, meaning that when you’re done, you shouldn’t have any references to PhoneGap in your code at all. It also makes developing quite a lot easier, since renaming my XCode project file by hand is cumbersome, and needs to be done every time I start a new project.