I apologize if this has been asked and answered - a redirection to a canonical resource that answers this question would be wonderful.
I've recently received a request to provide a build of a project I maintain for iOS, which is not a platform I have deep familiarity with. In particular, I'm not an app developer, have never submitted an app to the App Store, etc. The project provides a standard C++11 SDK: some headers and some libraries, installed to autoconf style $PREFIX/include
and $PREFIX/lib
directories. Satisfying the request would require providing pre-built binaries and headers targeting iOS. Assume for the purpose of this post that I can limit to newer iOS, say iOS 10.2+.
The typical delivery mode for this SDK for non-IOS developers has traditionally been as a header and a set of dynamically linked libraries. The project is designed around dynamic linking, and works well that way for many users.
However, my searches have resulted in wildly conflicting information on whether it is possible at all to use dynamic libraries in this fashion on iOS, and, if so, what the correct delivery mechanism / format would be when intending to deliver an iOS targeted SDK.
I have several questions:
First question: Is it possible, at all, to deliver an SDK that contains dynamic libraries (dylibs), such that application developers can build their application against the SDK and package the dylibs along with their application, producing something viable for inclusion in the App Store.
Second question: If the answer to the above question is "yes", are there any specific restrictions? I've seen some information that suggests that it is possible if and only if the dynamic libraries form a Framework (Framework Bundle?). Is anyone aware of any open source SDKs that ship this way that I might be able to use as a model?
Third question: If I were to ship a static SDK, I believe that code signing is not an issue for me as the SDK developer, since the application developer signs the final resulting artifacts with their own key, and that works because they are also signing any bits they picked up from the static libraries. It seems to me that if it is possible to deliver a dynamic SDK, then the burden for codesigning the artifacts would shift to me. Do I have that correct? Is it possible to deliver an app where different parts have different signing keys, as would be the case if I signed the SDK dylibs, and the application developer signed their application bits?
Fourth question: Will delivering the SDK as dylibs adversely affect usability for people who wish to build applications against it? If so, how?
Please note that I'm explicitly not asking about whether it is possible to dlopen
a library, or download dynamic code and use it, etc. My understanding is that that that is forbidden, for fairly obvious reasons. The use case here intends that the developed application would have explicit load commands referencing the SDK dylibs. Similarly, I'm not trying to get around any of Apple's restrictions: I simply want an answer that lets me know whether or not it makes any sense to even attempt to deliver this SDK as a set of dylibs, or whether I should redirect my energies into producing a static version of the SDK.
Static and Dynamic Frameworks:Static frameworks contain a static library packaged with its resources. Dynamic frameworks contain the static/dynamic library with its resources. In addition to that, dynamic frameworks may conveniently include different versions of the same dynamic library in the same framework.
What are the differences between static and dynamic libraries? Static libraries, while reusable in multiple programs, are locked into a program at compile time. Dynamic, or shared libraries, on the other hand, exist as separate files outside of the executable file.
Dynamic library - a unit of code and/or assets linked at runtime that may change. However, only Apple is allowed to create dynamic libraries for iOS . You're not allowed to create these, as this will get your app rejected.
A dynamic library is a programming concept in which shared libraries with special functionalities are launched only during program execution, which minimizes overall program size and facilitates improved application performance for reduced memory consumption.
You can codesign your lib with
codesign -s <Identity> libyourlib.dylib
add it to your application, and load it via dlopen
. This should at least work technically. I'm not sure, but I think Apple will probably not let your app through the App Store. You should try this if this is the easiest way for you. Note: Apple doesn't forbids the use of dlopen
in iOS, they even recommend its use for weak linking.
The main part of a Shared Framework is a dynamic library. So you might create a Framework with Xcode copy the build result to your project and replace the included binary with the universal binary of your dynamic library. Code signing should be done by Xcode automatically when creating the App bundle. Since Apple officially supports shared frameworks on iOS they will let this solution through the App Store.
If you can produce a static version of your library: You can create a shared framework in Xcode, and link it against your static library with -all_load
. This gives at least you a shared framework.
Note: Including shared frameworks or libs into an iOS app only make sense if there are multiple binaries (e.g. app and extensions) that will use it. If only the app will use the library there will be generally no advantage (saving space and memory) in using a shared framework / library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With