Question: How does one use a pre-built 3rd party dynamic iOS framework in an app target?
I develop a framework for iOS (Couchbase Lite). It’s open source but we prefer to distribute it in binary form, for several reasons (so we can QA the exact bits that a customer gets, so we don’t have dependencies on 3rd party package managers, etc.) This has always been a PITA because Xcode doesn't really support static frameworks on iOS, but we’ve been able to get it to work.
I’m now trying to create a dylib-based framework, for iOS 8+. I was hoping this would be easier, but it seems like it’s going to be uglier still, and the developer is going to have to jump through some hoops to build it into their app. The problem, as before, is with simulator vs. device builds.
— When building the framework, I have to create separate copies for iOS devices and the simulator. That results in two identical-looking “Foo.framework” directories that I'll have to ship in separate “Simulator” and “Device” folders.
— When the developer links the framework into their app, they have to link against the right copy for a device vs. simulator build. This seems to require making the Framework Search Paths build setting conditional based on the SDK, which is nontrivial to set up (you have to expand that one line out to 3 levels deep), so that you can point to the “Simulator” folder for a sim build and the “Device” folder for a device build.
— Then the framework has to be copied into the app bundle. But again, it’s a different copy of the framework depending on whether this is a device or simulator build. Here the problem is that the Copy Files build phase UI doesn’t provide any way to conditionalize by SDK, so I can’t make it copy the right copy of the framework. This is where I’m currently stuck.
The two solutions I can see are:
(a) Use a Run Script build phase instead, which can then use some logic to find the right copy of the framework to copy. It will also have to run the codesign tool manually. Yay, more complexity for the app developer and more pages to add to our setup instructions and more tech support questions for us.
(b) Or, build a fat framework (with both ARM and x86/simulator flavors). This requires more work when building the framework, but it’s the same nasty hackery I already know how to do for static frameworks. And it solves the problems I listed above because there’s only one framework. But it ends up making the framework twice as big as it needs to be because it contains code for both platforms. So the app developer may have to add a script build phase to run the lipo tool on the framework to strip the unnecessary architectures.
I’m kind of surprised that when Apple finally added support for real frameworks on iOS, they failed to think these problems through (unless I’m missing something!) I’m guessing that the only use cases they thought of were when the framework is a component of the app, like an extension, not a library provided by a 3rd party.
—Jens |