The “How to start, build, launch and market your first iPhone App in 28 days” series so far:
If you’ve been following along in our blog series, hopefully, at this point you should already be in the Build stage of your app. You know what you want to build and you know how to build it so the only thing we can offer at this stage are some tips, tricks and random helpful hints to make the build process a little easier and get you on the app store that much quicker.
Which Base SDK?
If you’ve just created your project, chances are it defaults to the iPhone OS 3.0 SDK or the newer OS 3.1 SDK. If you’re working off an older version, you might be on iPhone OS 2.2 or older. Which SDK to build upon is entirely up to you, but Apple requires that you at least test against OS 3.0 before submitting it to the App Store. What are the differences between distributing against the various versions?
- Pre iPhone OS 3.0 SDK (2.0, 2.1, 2.2, 2.2.1)
- Wider user base (can be installed on all OS 2.x and 3.x devices)
- No access to the 1000 new API’s introduced in iPhone OS 3.0 update
- Must also be compiled and tested against OS 3.0 SDK anyway
- Post iPhone OS 3.0 SDK (3.0, 3.1)
- Access to the latest 3.0 API’s (Push notification, In-App purchases, etc.)
- Some users will not have the latest iPhone OS installed on their devices (jailbroken iPhones and iPod Touch users, specifically)
If you would like to change the Base SDK (defaults to latest), select your Project file in the Groups & Files pane and then click the Info button. On the Build tab, under Architectures, you can select an older Base SDK to compile with. Remember though that Apple WILL test your application on an OS 3.0 device, so be sure to test it yourself as well. There are enough differences in the API that can cause problems on one SDK and not the other.
Debugging & Exceptions
Ah, debugging can be a pain sometimes. Actually, it can be a pain a lot of the time but with a few tricks here and there, your pain can be alleviated greatly. First off, if you haven’t already (shame on you!), watch the Stanford iPhone Development podcast on “Debugging Tips, Searching, Notifications, KVC/KVO”. There are some very useful tips in there, one of which I’ll be talking about here. If there’s only one podcast from Stanford that you’re going to watch, I would make it this one. But if you REALLY don’t want to watch it, or don’t have time, here’s the most useful tip from the video.
Set a breakpoint on objc_exception_throw
There will be times when an exception occurs and the Debugger reveals no clues in the stack trace as to where the exception occurred. You might be left guessing which line threw the exception or you could set up breakpoints to step through the code or you may even insert NSLog statements everywhere – but there is a better way. You can simply insert a custom breakpoint on “objc_exception_throw” and this will stop the debugger at the exact moment the exception is thrown. The difference though, will be that you will see the full stack trace and be able to trace back to the exact line that caused the exception.
To create this breakpoint, simply:
1) In XCode, select Run->Debugger
2) In Debugger, click on the Breakpoints button in the upper right corner (it might be hidden if your screen has low resolution or your Debugger window is narrow)
3) In the main window, double click on “Double-Click for Symbol” and type “objc_exception_throw”
4) Ensure the checkbox is checked to activate breakpoint
I would recommend you do this for every XCode project as it is extremely useful in handling exceptions. After I discovered this tip, this one breakpoint alone has saved me countless hours trying to manually track down exceptions.
This is probably one of the most common exceptions and is typically caused by trying to access an object that has already been released. These ones can seem hard to track down because it’s not obvious why the object is no longer in memory. I usually find it’s one of three reasons:
- I used “autorelease” and tried to access the object later on, hoping that it would still be there. Now, I hardly ever use autorelease. While it may be handy, I only ever use it if I know that I will not ever be referencing the object once I’ve changed scope.
- I lost track of my retain count and called “release” one too many times. This is easy to lose track of, especially if you’re passing an object across many controllers, all of which call retain/release on the object at different stages. Unfortunately, the only way you’re going to track this down is to trace your code backwards and see where you’re releasing it when you shouldn’t be.
- I never called “retain”. This I have done a few times when obtaining a reference to an object from another controller, releasing that controller but never retaining the object for the current controller. Make sure that you are retaining the object for your current use and that you also release it after you’re done with it – otherwise you’ll cause a memory leak, which we’ll talk about in a bit.
Memory leaks can happen quite easily in Obj-C because of the way memory management is handled. You add one too many “retain” statements or you forget to “release” an object after you’re done with it and you have a leak. One way to check if you’ve got any memory leaks is to run the Leaks tool in Instruments. To do this, simply:
1) In XCode, click Run->Start with Performance Tool->Leaks
2) This will start up Instruments with the Leaks tool running. Click on the Leaks instrument panel, and then click on the Extended Detail View button (see “1″ in the image above)
3) Use your application as you would normally. If you see any spikes in the Leaks panel, then those are possible memory leaks (see “2″ in image above).
4) A list of leaked objects will appear in the Detail View. If selected, each object will display it’s stack trace in the Extended Detail View to the right where you can determine where these objects are being used and possibly, where they are leaking.
Using Leaks takes a little getting used to but it is definitely useful when trying to find any memory leaks.
What if NSLog stops working
I like to use NSLog for debug statements but lately, I’ve been finding either XCode is buggy or I may have accidentally turned off some option to allow NSLog to output to the console. If this happens to you – don’t despair! Just use a simple printf() statement, like the one below:
printf(“%sn”, [@"NSLog is broken." UTF8String]);
Pinch Media, AdMob, Mobclix, Flurry, and many others, all offer iPhone SDK’s that allow developers to incorporate important analytics into their applications. This allows you to track usage of your application, as well as statistics on practically anything you want to track – within reason, of course. You should be clear to the user as to what you’re tracking and for what purposes you’ll be using this information for.
iPhone App Entreprenuer has a great 2-part post on the Ins and Outs of iPhone Analytics. For the record, we use Pinch Analytics, which is completely free and we only track usage in our applications in so much that we can see which features are useful and which areas could use improvement.
Testing – get some help
I know that with a lot of independent developers (or even developers in general), testing can be a sore point in the development cycle. Excuses for lack of testing range from having complete confidence in your own code (which you shouldn’t) to thinking you tested it adequately during the development (which you probably didn’t).
Bottom line is, if you’re the developer then you shouldn’t be the only tester for your app. Get it into other people’s hands and other people’s devices. You’re not going to be able to test all the different situations or interactions with your app since you’re the one who built it and you already have a predetermined “proper way” to use your app. Have your friends, family, colleague’s try it out. Seek out strangers (on the internet, not just some random people on the street – although, that may not be a bad idea as long as they don’t run off with your iPhone) and ask them to give you feedback. Find individuals that would be interested in your application and ask them to help you preview your application and give you feedback. Often feedback from strangers will be more honest and critical than from just your family and friends.
If you still can’t find anyone, you can always use Amazon’s Mechanical Turk service which allows you to hire people for small units of work. So you can offer a few dollars for an hour of testing your application and chances are you’ll find someone willing to do it.
Not only will all this testing provide you with some valuable feedback, but this is the start of your marketing efforts as well. If your app is good, you will generate interest and awareness that will definitely boost your app’s reach.
Release Early, Release Often
I’m sure you’ve heard this before, but this rule is just as appropriate for iPhone Development as it is for web development. Now, it’s not to say that you should ignore everything we’ve just talked about with testing and release your app full of bugs (if your app crashes or bugs and Apple finds them, they WILL reject your app). But there will come a point where you have to decide whether you hold off submitting your app because you want to include 1 or 2 extra features, or just submit it as feature complete and add the extras in an update. Here are a few tips to help you with your decision making process:
- Make sure your app is bug-free, but don’t let feature creep postpone your submission. Features and nice-to-haves can be easily incorporated into your update and you’ll have adequate time to test these new features rather than rushing to put them into your 1.0.
- As stated above, Apple WILL reject your app if they find that it crashes or has buggy behavior. That being said, Apple’s reviewers aren’t the most consistent bunch as I’ve heard stories where apps have been rejected, resubmitted with no changes to the code, and then approved. Go figure. Also, crashes and bugs generate bad ratings/reviews and bad ratings/reviews can sink an app early in it’s life.
- Currently, it appears that new app reviews take anywhere from 1 to 2 weeks. Updates are typically faster at around 3-7 days. With this in mind, you might want to submit a stable version of your app as soon as possible so that it can be reviewed and approved. Meanwhile, continue adding new features to your app and once your 1.0 version has been approved, you will have your first update ready to go and this time, it should be much quicker. Review times in general seem to be much quicker now – iHeartRate 1.0 took almost 1 month to approve but that was back when OS 3.0 was released and there was a mad rush of updates and new apps.
- Plan to make frequent updates. Every update you do brings increased exposure simply because your app gets bumped back up to the top of the New Releases list of your category (as long as you follow the Release Date “Trick” described below).
The key thing to keep in mind that while you want to release a quality app, you will always have an opportunity to improve it and in fact, you will be EXPECTED to improve it. App updates are a necessity and you should learn to embrace it as part of the app’s life cycle.
Release Date “Trick”
So, the App Store release date is a funny thing. When you first submit your application, you are asked to give a Release Date (date that the app will appear on the store). Of course, there’s no real way to know when Apple will approve it so naturally, one would think that they could set it to the current date so that it will appear on the App Store as soon as it’s improved. This will cause the following to happen:
- When the app is approved, it will in fact appear on the App Store immediately (well, it’ll still take a few hours to appear in the search index)
- The App Store will take the EARLIER of either the Approved Date or the date you set as your Release Date (the one you set when you submitted your app)
- Since you set the Release Date to the day that you submitted, your app won’t appear at the top of the New Releases list. It’ll be pushed back all the way to the date you submitted – this is obviously not ideal.
So what do you do? Well, when you submit, set your release date to some far off date in the future. Then when your app is approved, set the release date to the day it was approved and your app will appear on the New Releases list with the correct date. This also applies to Updates, except that when you submit your update, don’t change your Release Date (if you set it into the future, it will take your app off the App Store!). Wait until your Update is approved (check iTunes Connect every day yourself as Apple doesn’t always send you notifications) and then change the Release Date on the day it is approved to the current date. Again, if you don’t do this, Apple will take the earlier of the two dates (Approved Date and specified Release Date) as your release date. This will ensure that you get bumped back up to the top whenever you update your app.
Last but not least, is to prepare your application for distribution. Here are a few pointers to help you get your app into the hands of the users…
If you can, try to keep your application to be less than 10MB. The reasoning behind this is that if your user wants to download your app over 3G or Edge (*shudder*), then your app MUST be less than 10MB. Otherwise, they’re going to have to either download via iTunes or connect via WiFi. Why does this matter? Well, that means that when a user is standing at a bus stop and surfing the App store for something cool and wants to buy your app, he can’t, if it’s 10MBs or more! You want it to be available for them whenever they want it and not make them go home and sync to get your app. So, make sure that you flatten all your images and remove any frameworks and API’s that you’re not using to reduce the size of your application.
App Store Distribution
When you submit your application to iTunes Connect, you have the option of uploading it through the web browser or you can check off “Upload Binary Later” and upload via Application Loader (also available through iTunes Connect). Being your first app, I highly recommend using Application Loader as it checks to make sure that you have indeed used the proper code signing profiles to compile your app. The browser interface does no such checking. There’s nothing worse than waiting weeks for your app to be reviewed only to find out at the end that you didn’t compile it correctly. Use Application Loader and it will ensure that your uploads are code-signed.
Ad Hoc Distribution
Ad Hoc Distribution is a great way to get your app into the hands of testers and other users to provide you with feedback. However, getting Ad Hoc distribution to work can be another story altogether. We had some issues with Ad Hoc but I believe we’ve found the magic combination. For the most part, you should follow the iPhone Developer Program User Guide for Ad Hoc Distribution, with the exception of the following changes. And best of all, this works for deploying your App to both Mac and Windows users.
1) In Step 9 of the iPhone Developer Program User Guide:Building your Application with Xcode for Distribution, name the file “dist.plist”. (I don’t know why this works exactly, but I found when it was named “Entitlements.plist”, it wasn’t getting found during the Build)
2) In Step 12, type in “dist.plist” as the file name instead.
3) After successfully building your Ad Hoc Distribution, use Reveal in Finder to locate the .app archive. Open iTunes, click on Applications and drag BOTH the Ad Hoc Distribution Profile (.mobileprovision file) and the app (.app archive) into the Applications page (your application should now appear in the Applications page of iTunes, if done correctly, and the next time you sync, it should load onto your device).
4) Right-click on your Application’s icon and select Show in Finder. This will reveal a “.ipa” file which is basically a compressed version of your application for iTunes.
5) Distribute the Ad Hoc Distribution Profile (.mobileprovision) and the “.ipa” file to your users. Ask them to drag and drop BOTH files into their iTunes Application page and then sync. After that, it should be installed on their devices.
Please remember that for each new user, you must add their device’s UDID to the Distribution Profile on the iPhone Developer Program Portal, download the profile, re-build your app with the new profile and distribute the new “.ipa” file along with the new profile.
Well, I hope that was helpful and I apologize for all the numbered lists – sometimes it’s just easier to gather tips and tricks into lists. With that, I’ll leave you with a link to Matt Legend Gemmell’s invaluable iPhone Development Emergency Guide – a fantastic guide to even more “gotcha’s” and tricks when developing for the iPhone.