Forrest Forrest - 1 month ago 15x
iOS Question

When should we use "embedded binaries" rather than "Linked Frameworks" in Xcode?

There is a good question about the difference between those two options as described in Link Binary with libraries VS Embed Frameworks.

Seems like we have options to use them both, just wonder which case we should use embedded binaries better, or rather than linked framework ?

Any solid examples to address this more clear? Thanks

par par

The question you linked references the "Link Binary With Libraries" functionality, which is somewhat different than an embedded binary.

"Link Binary With Libraries" means what you'd expect it to with respect to linkage: Regardless of whether the binary is a static library, dynamic library, or framework it will be linked to your object code at link time after compilation.

When you think of linkage with a static library, what happens is pretty clear: the linker copies the code from the library (e.g. libFoo.a) into your output binary. Your output file grows in size but doesn't need to resolve any external dependencies at runtime. Everything your program needs to run (with respect to the static library) is present after it is built.

With a dynamic library (.dylib, or system-supplied framework), the expectation is that the library you are linking against will be present somewhere in the system's dynamic-library loader path when you run your program. This way you don't have the overhead of copying all the third party external libraries into your binary, and all the different programs on a computer that also link to that library will be able to find it, which saves minimally disk space, but also potentially memory space, depending on how and where the system caches libraries.

A framework is much like a dynamic library, but can contain resources in its directory structure (images, audio, other frameworks, etc.). In this case a simple static-library or .dylib file won't cut it so you might have to link to a framework just so it can find what it needs to run properly.

When you link to a third-party framework (say something you downloaded from github and built yourself), it might not be present on the system you intend to run on. In this case, you'd not only link to the framework, but embed it inside your application bundle as well using the "Copy Frameworks" phase. When your program runs, the runtime-linker (aka the resolver) will look inside your bundle in addition to the system loader path, find the embedded framework, and link it so your app will have the code it needs in order to run.

Finally, what is properly an "embedded binary" is an executable you both embed in your application bundle via a Copy-Files Phase, and that you execute yourself, perhaps with a call to popen() or similar. The embedded binary may be called by your program, but it isn't linked with it. It is a fully external entity (like programs in the /bin directory).

In practice, for system-supplied libraries and frameworks you will link against them and that's all you need to do.

If you need to link a library you built that doesn't need any embedded resources (i.e. doesn't require a framework to exist), then you can just link against a static library. If you find you have multiple modules in your program that want to use the same library code, then converting it to a framework or dynamic library and linking against that can save space and may be convenient (particularly if memory usage is a concern).

Finally, frameworks can include not only resources, but header and/or license files. Using a framework to convey these files is actually a convenient distribution mechanism so often you may want to incorporate a framework just so these things can tag along with your binary (i.e. license requirements may make this mandatory).