Tuesday, July 5th, 2011
My current set up in Xcode 3 runs something like this:
- For day to day development, I use the Debug configuration. Pretty standard. No real correlation between running the product on the device and simulator.
- When I want to do — or simply try out — a Release style build, I switch to the release configuration. I do this from time to time just as a sanity check. 99% of the time I use Release, it’s on the device.
- Even more rarely — once a week at the maximum — I need to do a release. In my case, these releases are usually milestone builds for clients, just to show how the application is progressing.
Even still, I have a couple of requirements about these release builds:
Firstly, I need to be able to run and test the exact build I’m going to send to a client. Seems foolish to do anything else.
Also, I have a somewhat complicated, but I don’t think unreasonable release process. It goes something like this: After running and doing a final smoke test on the release build, I run a script I’ve developed. This script:
- Copies the dSYM from build/Release to dSYMs/
- Adds a tag for the current version (based on the CFBundleVersion)
- Bumps the CFBundleVersion
- Runs the PackageApplication script included with Xcode to create a .ipa file from the .app in build/Release
- Opens a Mail message with that .ipa file attached
It also has support for parsing & incrementing the CFBundleShortVersionString key and a couple other things.
So to be clear, I’m backing up the dSYMs for each release in source control and trusting my email provider to host the builds of old versions of the applications (only reason I’ve found to need those EXACT old versions is to re-sign them).
Also note that this script isn’t run from Xcode, and in fact it wouldn’t be a good idea to do that. (I’m working on a version that has interactive capabilities to prompt the user if it notices odd things, like if the build it finds is older than a certain threshold or signed in a way that’s probably wrong.)
I think these are all pretty reasonable requirements. It’s certainly not the most Xcode-y way of going about doing this, but it makes sense to me and I think is at least somewhat internally consistent.
Where Xcode 4 falls down
Firstly, the new default location for built products — which is in
~/Library/Developer/Xcode/DerivedData/$AppName-$RandomSeriesOfDigits1 and seems to have been chosen so schemes and workspaces don’t step on each other (totally reasonable) — totally breaks my script. I’m totally not against having to add more options to my script (plus some sensible defaults) for specifying which scheme or workspace or whatever is wanted, and then having my script look up the location for that scheme. But there doesn’t seem to be any way to do that.
(Moving my built products back into SRCROOT seems like it’s begging for disaster further down the road, and I’m really hesistant to do this.)
I also find the combination of schemes & actions totally unnecessary. I don’t understand what problem they’re trying to solve. I’ve never found configurations, especially with .xcconfig files, to be inadequate.
The default actions are both too limiting — in my workflow there are multiple types of “Archiving” (more on that word later) — and also way too broad — testing and analyzing and running are all totally overlapping for me. I also can’t imagine a workflow where I’d want to configure more than one of the actions for a particular scheme — that seems like something you’d want in a target. Maybe I’m missing something.
Aside: Core Data
One problem not mentioned above is Xcode 4’s handling of Core Data. All of the below applies to the only released version, 4.0.2.
- You cannot change the model version identifier. rdar://problem/9592700 which is duped to rdar://problem/9006105 (which I see as open).
- When you create a new model version, what you enter for the model’s name in the into the wizard doesn’t stick. I.e. “MyApp (5) 2” is the default and no matter how many times I tried to change it to “MyApp (6)”, the resulting file would be created as “MyApp (5) 2”. Infuriating.
Returning to the main thrust of the post, about Xcode 4’s failings
Because of the above problems with Core Data, I still need to use Xcode 3 somewhat frequently — at the very least to deal with Core Data model files. It’s really unclear to me what exactly is going to propagate back from Xcode 4 in terms of schemes, actions, etc. Not creating an addition scheme seems to not break things for me, but I have not played with this out of fear of breaking it.
Finally, I’d like to address “archiving”. The standard archive action frankly blows for one big reason: I have multiple machines. It’s largely worthless to have half the dSYMs on one machine, half on the other. Moving the dSYMs into source control and keeping the .ipas in email is a pretty good solution and works well. Having to dick around in the Organizer is so annoying. (The Organizer itself seems to be a random collection of functionality the designers that weren’t iTunesy enough to fit in the main UI.)
This situation honestly sucks, and I see no way to use Xcode 4 for releasing software (especially when it involves Core Data) — for the foreseeable future I’ll continue to use Xcode 3 for doing so.
(One last thing: Xcode 4 is a total boor on a 13” screen. It’s nearly impossible for me to use comfortably. (If you tell me my font’s too big I will hurt you.))
An example of this is: