8

AFAICS, any serious iPhone developer must make and use static libs on a regular basis, or else condemn themselves to buggy, hard-to-maintain, unwieldy projects. But Apple refuses to provide any official docs on the process (just circular references: "dont do static, use dynamic! ... we don't allow dynamic on iPhone, use static!")

I have spent more than 6 months experimenting with this; I have deployed static libs in multiple iPhone apps on the App Store; I came up with a nice, working system based on Universal Binaries ... that IMMEDIATELY BROKE when OS 3.x came out (LOL); ... I now have a new system that works with all versions of the iPhone OS.

I have read the related questions on StackOverflow on this topic, and they either don't go far enough for full usage of static libs, or require you to use one or more external command-line tools, hence breaking out of the IDE. What's the point in an IDE if you can't get everything to work inside it?

I think I've found a way that works, entirely inside Xcode. But I'm really nervous, based on past experience...

I would love some feedback on whether this time - finally! - through trial and error, I've actually got it right.

OR ... even better ... I would love to find someone who will tell me exactly how you are "supposed" to do it, how Apple expects / wants / requires you to do it.

The process I have is sufficiently convoluted that I've written it up into two blog posts:

  1. First post: basic assumptions and problems
  2. Second post: methodology, and step-by-step process

PLEASE NOTE: there are many things I don't know about iPhone and Cocoa programming that I ought to; I know there's a lot wrong with what I'm doing, but I'd rather share it and possibly get shouted at than keep quiet and never learn what I'm screwing up.

Thoughts? Improvements? Or even ... am I a complete fool, and there was a much, much easier route that I was dumb enough not to notice in all my searching?

Thanks in advance...

Adam
  • 32,900
  • 16
  • 126
  • 153
  • 1
    I disagree with your assertion that static libraries are absolutely necessary for iPhone applications. I've heard many experienced Cocoa developers explicitly caution against spending all of your time writing frameworks and not just sharing source code between various projects (one example post on the subject can be found here: http://wincent.com/a/about/wincent/weblog/archives/2006/11/son_dont_repeat.php ). For common projects like Three20, I can see the advantages, but it sounds like your questions are directed towards your own in-house code. – Brad Larson Oct 14 '09 at 20:13
  • 2
    Libraries are good (or "required") for: * distributing your code without distributing the source * encapsulation + data-hiding (enforces non-modification of classes and interfaces) * fast build times With Obj-C, you can get around the encapsulation that libraries provide, but ONLY in a way that places all custom code inside the project doing the customization - which is a nice, clean compromise. Libraries aren't perfect, but they greatly speed up iPhone development. They are also - as far as I know - the *only* way you can distribute binaries without source? – Adam Oct 15 '09 at 10:35
  • 2
    Apple's Frameworks would be even better, providing: * easy Interface Builder integration in libraries (can provide NIBs easily) * automate header-file distribution (new headers "automatically" picked up, for instance) * ditto other assets - image-files, property-list files, etc Having distributed iPhone libraries for different groups where NIB / IB integration was "tricky", it would have been a huge timesaver to have had good NIB integration. I believe this is a fairly typical use-case from what I've seen. Sadly, as far as I know, we are not allowed to do Frameworks on iPhone. – Adam Oct 15 '09 at 10:36
  • 1
    Sure, it's a common noob mistake to try and put all their "useful" code into a single monolithic library - I'm sure this is just as common with Cocoa as with other platforms. But that's not a good reason to give up on libraries. Instead, it just means that the inexperienced coders need to be careful. I'm unconvinced by the blog post you link. It features some huge flaws which seem to fatally undermine the argument, e.g. his fix wasn't "svn externals" it was "learning how to factor his project" (i.e. becoming a better/wiser programmer) - i.e. a framework would still have been fine, no? – Adam Oct 15 '09 at 10:40
  • (PS: sorry for the illegibility of comments - I didn't realise it would delete the formatting of bullet lists etc) – Adam Oct 15 '09 at 10:40
  • You bring up many good points as far as where static libraries are useful. My only issue is with the tone of the language you use in the question (and the linked writeups). Most of the iPhone developers I know (including myself) have not employed static libraries in our applications for common code, with the exception of third-party libraries, and yet many of the applications are still clean and easy to maintain. – Brad Larson Oct 15 '09 at 14:56

4 Answers4

3

You may find this tutorial useful from someone who has done this recently:

http://kyleroucis.com/Kyle_Roucis/Blog/Entries/2009/10/7_Custom_Embedded_Static_Library_for_iPhone.html

Kendall Helmstetter Gelner
  • 74,769
  • 26
  • 128
  • 150
  • Thanks for the link. Unfortunately, that doesn't help at all - it ONLY works where you have the full source code AND you are willing to make direct xcodeproj references inside your SCM (which would be very brave, I think). I covered this in the first of the two blog posts. – Adam Oct 14 '09 at 10:17
1

Something I missed out, because I haven't included any categories in my own static libs:

You MUST include the linker flag "-ObjC" if you use categories, or else your static lib will be "missing" some bits and pieces when you try to use it in projects.

I have heard of people placing this flag in 6 different places, but the one that seemed to work for me was:

In library project (not app project, strangely), go to build settings, and add a user-defined setting:

OTHER_CFLAGS = -DObjC

...although I believe it ought to be instead:

Other Linker Flags = -ObjC

(NB: this has the side effect of setting the OTHER_CFLAGS automagically inside the GUI)

Also, I've heard a lot of people claim it should go in the application project, but they were all embedding their projects together, not compiling true static libs, so I suspect they just got lucky.

ALSO ...

XCode / Iphone OS 3.0 seems to have a bug where you also need the -all_load flag (use exactly as with the -ObjC flag above). There's some StackOverflow questions about the use of -all_load flag with 3.0, so have a look at them for more info - I'm not really experienced with that.

Adam
  • 32,900
  • 16
  • 126
  • 153
0

And some more helpful advice, in terms of how to package up the result:

Can you reference Xib files from static libraries on the iPhone?

NB: interesting that the author of that comment says they couldn't get bundles to work with static libs. I too tried that, when I found Frameworks wouldn't work, but found that Xcode / iPhone SDK was hard-coded to prevent you from even using bundles in this way :(. I thought it might just be my mistakes, but if others have tried and failed too, then maybe not.

Community
  • 1
  • 1
Adam
  • 32,900
  • 16
  • 126
  • 153
0

Sorry to be late to the game, but I recently had some help creating a static library so that people can use my data structures library on iPhone OS. See http://cocoaheads.byu.edu/code/CHDataStructures and check out from Subversion to see first-hand how I've created a static library. I haven't gone to the trouble of creating a Simulator-friendly version, but it works on the device and wasn't terribly complex.

Quinn Taylor
  • 44,553
  • 16
  • 113
  • 131
  • I'm sorry, but you've missed the point of the question. According to your docs on that site, all you've done is to link two Xcode projects together, just as in the StormyProds example. Try shipping a binary-only version of your library and then you'll see what all the fuss is about! – Adam Dec 11 '09 at 11:41
  • I think you'll find that my Xcode projects for this library are a little more advanced than just that — they actually do produce binary-only versions (both a framework and an iPhone static library). Linking the source project is a simple way to go, and was suggested by a contributor, but I prefer to copy the binary and headers into the client project. Eventually, the disk image produced by the Deployment target will include both the framework and the static library, with no code but header files. I need to make tweaks so it works in simulator and on-device, but it's pretty close as-is. – Quinn Taylor Dec 11 '09 at 22:57