I’ve now deployed iPhone static libraries in two (live) applications, and numerous updates.
This is a process that is seemingly (*) 90% undocumented by Apple, despite being (IMHO) absolutely essential for any professional iPhone developer.
UPDATE: Apple changed everything (again) without telling developers (again) and broke everything (again).
Current versions of Xcode (the minimum that Apple allows you to use) will *not* work with the architecture-link part of this blog post.
Instead, see this StackOverflow question I asked (and answered) with an updated technique: http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
[(*) - if there's docs, then I've not found it in over 6 months of googling, searching Xcode doc libraries, and asking everyone I know. I will feel stupid if it's there and I haven't found it, but I have honestly tried very hard to find it!]
I have sought help in numerous expert forums and mailing lists – and generally discovered that no-one else is quite sure how to do it either, although I’ve seen some funky ideas and methods that others have come up with.
Through trial and error I’m pretty sure I know how to do it now – but I still have no idea what the “correct” approach is – so I’m writing up my best knowledge here, and I’m going to spread it to as many people as possible to get feedback from the 30,000+ other iPhone developers around the world.
First, some background…
The basics – Apple documentation
Apple’s documentation is absolutely terrible. It is shamefully, inexcusably, bad. It tells you:
Don’t use static libraries; static libraries are for idiots; you SHOULD use dynamic libraries for everything. This makes life easier for you (as a developer) and a lot cleaner for your users.
This is all ENTIRELY TRUE and extremely worthy.
Sadly … Apple also states (if you follow their instructions for dynamic libraries on iPhone)
We forceably prevent you from using dynamic libraries on iPhone; dynamic libraries are banned; you MUST use static libraries for everything
Apparently, someone at Apple “forgot” that they removed their docs on making static libraries some time ago, replacing them with notes to “use dynamic libraries and frameworks instead”.
The basics – Frameworks
Frameworks are awesome – well done, Apple! – but apparently they require dynamic libraries. I have never yet found anyone who managed to make an Apple Framework for iPhone; I don’t think it’s possible (although I keep trying…).
The basics – Universal Binaries
Universal Binaries are awesome – well done, Apple! – but Apple decided they were “too good for you, suckas!”, and removed them in iPhone OS 3.x.
At least, I had techniques that successfully built and deployed UBs on iPhone in 2.2.1, but completely stopped working in iPhone OS 3.0. As far as I could tell, none of this – none of it! – is documented (of course!). I have given up on UB’s. But, if someone can show me an officially accepted way of doing UB on iPhone OS 3.x, I will be very happy.
(NB: it *must* be officially accepted: I suspect that Apple deliberately broke / removed UB support for 3.x)
The basics – Source-code builds
The Worst IDE in The World ™
HOWEVER … it does have very good support for embedding references to one project (LIB) inside another project (APP), so that whenever you re-build APP, it automagically re-compiles LIB if – and only if! – it is necessary.
However, that is only of relevance if:
- You have the complete source code AND build settings to ALL libraries you ever use (this is very unlikely)
- Your distributed, caching, build system is complete crap, and you don’t actually use it
- Your SCM is exceptional, and deploys entire “related” Xcodeproj directories for all revelant projects (this is very VERY unlikely)
- You have a super-fast machine that compiles REALLY REALLY fast, and you don’t mind doing triggered re-builds of projects
- You don’t mind spending several weeks tracking down non-existent bugs because of a dynamic mis-matching of library source versions
So, basically … it’s a useful feature for the hobbyist programmer, but most real studios can’t afford to rely upon it.
The basics – Device-only builds
The iPhone Simulator that apple provides to all iPhone developers is EXTREMELY good. It has four bugs / problems:
- It’s too fast (it makes NO attempt to run at the same speed as an actual iPhone)
- It doesn’t simulate the different hardware revisions (you cannot select “3GS mode” as opposed to “3G mode”)
- It doesn’t simulate multi-touch (and a few others, like “vibration”) and (bizarrely) doesn’t support odd things like some of the built-in animations
- It uses a different CPU architecture – intel only, as opposed to the iPhone’s ARM chips
It takes a LONG TIME to download a freshly-compiled iPhone app to your iPhone – approximately 10 to 30 seconds, on average. This can easily extend the “change, compile, test” cycle on a (fast) Mac from about 20 seconds to about 40 seconds – i.e. literally a 2x decrease in productivity.
Hence it is essential for serious iPhone devleopers to work on the Simulator as much as possible, and switch to the Device periodically (perhaps using the Simulator 30-50 times an hour, and the Device merely 3-5 times an hour).
Followup, with details on how I solved all this: