mangochutney: Setting up Notational Velocity to sync with Elements
Andrey Subbotin: iPhone 4 @2x Assets Made Easy
iOS Wireless App Distribution – JeffreySambells.com
Understanding iOS 4 Backgrounding and Delegate Messaging @ Dr. Touch
Volon Bolon: Tuning Performance With Instruments
iPhone Development: NSOperation Xcode File Template
Using Blocks in iOS 4 — the Pragmatic Studio
‘A Few Git Tips You Didn’t Know About’ — This Is Super Handy.
Of Ad Hoc and App Store Signing
With the recent release of Xcode there are now some really great tools for archiving and distributing builds. How that works is beyond this post, but you can find more at Apple’s Dev Center and Erica Sadun’s devsugar article ”A better way to share ad-hoc builds”.
While these tools are great for a single developer, or a very small group that has a single person responsible for builds, they are far from ideal for large groups. At my day job we are a pretty large outfit. During the course of the day engineers will make builds for themselves, but in the end we have a build system where all official builds come from. Depending on the project there are anywhere from one to four configurations that get built for every target when there are new commits. Doing that by hand would be time consuming and a waste of a human resource. We have a build system to handle all of this automatically for us (that can be the focus of another post later).
One of our core philosophies is that the app we test is the one that must be shipped to Apple for release. Testing the exact same binary we’re going to be shipping for sale gives us a high degree of confidence in what we’re shipping. Why would you ever ship bits that you haven’t tested? You shouldn’t. If we built separate ad hoc and app store binaries and only tested the ad hoc we’d be doing our customers a disservice. Fortunately there is a way around this, and you only need two builds and three provisioning profiles to cover all your bases.
In the Dev Portal you’ll want to generate the three profiles to be used. When you’re doing this consistency in naming is key. I like to label all my files (now that I’ve learned) so I can target them easier in the future. The labeling scheme I use is:
- Development profile: SomeApp_development.mobileprovision
- Ad Hoc profile: SomeApp_ad_hoc.mobileprovision
- Distribution profile: SomeApp_app_store.mobileprovision
Fig 1: Don’t forget to set the bundle identifier to the same as your AppID and profiles.
A lot of people start development with the wildcard development profile for their developer account. That’s fine for getting off the ground with a minimum of fuss, but I really recommend getting into the practice of signing with app-specific profiles as soon as possible. The major reason is you’re signing against a profile that’s targeted at your bundle identifier and you’ll know immediately if it is incorrect. Another thing you want to do is mimic in your development environment as close a conditions as possible to what you’re going to be submitting. Running on a wildcard is fine and dandy, but it’s not anything like making sure you’re app is ready to submit to Apple, especially if you’re going to be using In-App Purchasing and Push Notifications (since IAP and Push don’t work on wildcard App IDs).
With this system you only have two build configurations you’ll need. You may, of course, want more to fine tune things, but really two is plenty to get where you’re going. The first configuration we’ll call Debug (the default name in Xcode). This will be a build that is signed with the development profile we created above. We’re not so worried about this configuration, it’s pretty standard and should be used for your iterative builds that you’re going to test on your devices.
Fig 2: Set the Debug configuration to the development profile.
The second configuration we’ll call Release (again, the default name in Xcode). From this one we’ll build optimized builds that can be packaged and sent to either our QA group, beta testers, or Apple to put into the App Store. From this build we’ll generate ad hoc releases and app store binaries. We will not, however, ever have to change the code signing setup once we’ve got it in place. That’s right, we’ll sign with one profile and distribute two different times. I didn’t believe it at first myself, but now that I’ve seen it I love the simplicity of building apps this way.
Fig 3: Set the Release configuration to the app store profile.
In your Release configuration set the code signing to use the SomeApp_app_store.mobileprovision. That’s it. Build as many times as you like, but you only ever code sign with the app store profile you created. When it comes time for you to send a build to beta testers you take the SomeApp.app bundle and the ad hoc profile and zip them into an archive (You can make an IPA file like iTunes does, but I don’t have any experience to share on that right now). The testers then install both files via iTunes, Xcode, or iPhone Configuration Utility and are able to run it on their devices. After a clean bill of health from testing you can then take that exact same SomeApp.app bundle and zip it and submit it to Apple for review. Simple. Easy. Less headaches.
Subversion to Git Roadbump: Canonical Version Numbers
Recently, a major project at work that’s in the middle of continued development was switched from Subversion to Git. There was a bit of wailing, and some gnashing of teeth, but with a lot of planning and testing beforehand the switch went smoothly. Of course, with even the best of intentions of making life easier for the engineers there were some rocky spots after the dust settled. The major bump we’ve seen so far is the lack of canonical revision numbers and confusion on lesser technical people that rely on the code base.
First, a little background on Subversion. Subversion keeps an positive number for every commit to the central repository. A commit could be one line in one file or one thousand lines in twenty files. Each one is a new revision. Something along the lines of r101, r102, r54234, you get the idea. Somewhere along the way after the company started and was using Subversion people began to rely on these version numbers. A producer could tell if a build marked with a revision number contained a fix or not. QA was able to assign or close bugs based on what build they were testing and if the engineers told them the fix revision.
All was right with the world and then Git came along and made it even better. Git is a far superior experience for the engineers (and that’s a whole other article). Git uses SHA1 hashes to denote revision numbers. The long form is 40 characters like 96132ce6bab4c27aa4cb40d8655cc8563f19b46b and the short form is the first seven characters like 96132ce. Far more complex than the revision numbers from Subversion, and that’s where the plot thickens.
In the end it turns out that SHA1 hashes cause some people’s eyes to cross and their brains to smoke. In the ensuing chaos bugs were getting closed and re-opened incorrectly. People were having trouble communicating what builds to look at, or even telling if a build contained a fix or not. Compare r101 and r102, you know the fix is in 101 so 102 or higher has the fix. In Git it’s 96132ce and eaf872a where you can’t tell right off if the latter is newer than the former.
The production staff was at the breaking point and came to us with a plea, make it easier to compare revisions. While we could have ignored it and forced them to learn to deal with Git revisions that is a path to darkness and anger. We don’t do that. We’re co-workers and we like each other and together we make cool stuff. So digging into Git I went, sure that someone had solved this issue in an elegant way already.
Sure enough, even the Git project itself has a canonicalish revision numbering scheme. Taking a cue
from the Git masters I looked at git describe. The describe functionality of Git takes your
current revision and counts backwards to the previous tag and then presents the tag and that number
along with a short format revision hash to the user. Cool, we’re looking for counting. Running it on a
release branch we get a silly thing like “beforemergeafterpatches-123-ge47ac1”.
That’s great, but that tag isn’t necessarily interesting from a production point of view. Thankfully Git lets us specify a match parameter for the tag name. The Git project tags versions with vX.Y.Z when they start working on that revision. When they match for that tag they get something like “v1.0.1-45-g67e4ad”. That’s much more reasonable and very much what we’re looking for. Something along the lines of:
% git describe --match 'v[0-9]*' --abbrev=4
The project we’re working on is following it’s own branching model that’s been worked out ahead of time and each release to be worked on is in it’s own branch (if you don’t have a solid branching model I suggest you check out nvie for a good place to start). At the creation of the branch the engineer also makes an annotated tag that follows a set pattern we can match against. This gives us gives us a nice and tidy string like ‘gamename_1.23-58-g3fad587’, perfect for our producer and QA needs while also giving engineers enough information to get to a spot in the repository. As a bonus we also know what version of the app this commit is working towards, and that helps with builds.
Now we have a canonicalish bit that can be passed around from engineering to production to QA and back. Engineers (and other repository users) can generate this information on the fly. Builds will be tagged with this string so they match what the engineers are telling people. People will be happier. Rainbows will shine. Puppies will lick your face. You’ll get to move on and do cool stuff.