Skip to main content

Static Library, Dynamic Library, Framework Which is best way to distribute Custom Code?

If you’ve been developing for iOS for some time, you probably have a decent set of your own classes and utility functions that you reuse in most of your projects and shared with teams. 

Well, there are different ways, the easiest way to reuse code is simply to copy/paste the source files. However,  this can quickly become a maintenance nightmare. Whenever you update the source code, you have to update the changes to all the files between teams and projects, Since each app gets its own copy of the shared code, it’s difficult to keep all the copies in synch for bug-fixes and updates. Also, this will not work if you don't want to expose the implementation details.

When developing iOS apps you rarely implement everything from the ground-up, because operating systems, as well as the open-source community, offer a large amount of functionality ready-to-use. Such pieces of functionality are usually packed in a distributable form known as the library. In this article let's explore static and dynamic libraries and frameworks which are the two major types of building blocks in iOS and macOS projects.

Here you will share the library with the team and they can use it in their projects. Whenever you're making any changes in the code, you just update the library and share with them. This makes everyone's life easier as all you have to do is just keeping the updated library.

Static Library(.a) :-

A unit of code linked at compile-time, which does not change. However, iOS static libraries are not allowed to contain images/assets(only code). You can get around this challenge by using a media bundle though. A better, more formal definition can be found on Wikipedia here.


Static libraries are collections of object files. Object files have Mach-O format which is a special file format for iOS and macOS operating systems. It is basically a binary stream with the following chunks.

  1. Header: Specifies the target architecture of the file. Since one Mach-O contains code and data for one architecture, code intended for x86-64 will not run on arm64.
  2. Load commands: Specifies the logical structure of the file, like the location of the symbol table.
  3. Raw segment data: Contains raw code and data.

An attentive eye might have noticed that Mach-O files support single architecture. Then how can an app with lots of static libraries run on all devices and even the simulator?

The answer is the lipo tool. It allows to package multipole single architecture libraries into a universal one, called the fat library, or vice-versa. Here you can read more about lipo.

  • You’ll need to build a library for the same processor architecture as the client code. If you, for example, working on a library for the iOS application you will need to create a library for iOS Simulator and iOS devices.

Dynamic Library(.dylib) :-

However, linking to libraries create large executable files and wastes memory. One way to reduce the file size and memory footprint of apps is to reduce the amount of code that is loaded at app launch.

Using dynamic libraries instead of static libraries reduces the executable file size of an app. They also allow apps to delay loading libraries with special functionality only when they're needed instead of at launch time. This feature contributes further to reduced launch times and efficient memory use.

To load the dynamic libraries at runtime, apps should use a set of efficient and portable functions, called dynamic loader compatibility functions. Using these functions ensures that dynamic libraries are loaded in the most efficient way and facilitates the porting of apps from one platform to another.

All iOS and macOS system libraries are dynamic. Hence our apps will benefit from the future improvements that Apple makes to standard library frameworks without creating and shipping new builds.




For more details please visit Apple developer.

Dynamic libraries outside of a framework bundle, which typically have the file extension .dylib, are not supported on iOS, watchOS, or tvOS, except for the system Swift libraries provided by Xcode.

Dynamic Text Based .dylib stubs (.tbd) :-

When we link system libraries, such as UIKit or Foundation, we don't want to copy their code entirely into the app, because it would be too large. Linked is also strict about this and does not accept shared .dylib libraries to be linked against, but only .tbd ones. So what are those?

Text-Based .dylib stub or .tbd is a text file that contains the names of the methods without their bodies, declared in a dynamic library. It results in a significantly lower size of .tbd compared to a matching .dylib. Along with method names, it contains the location of the corresponding .dylib, architecture, platform, and some other metadata. Here is how typical .tbd looks when opened in the text editor.

--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 6FFAC142-415D-3AF0-BC09-336302F11934' ]
platform: macosx
install-name: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libQuadrature.dylib
objc-constraint: none
exports:
- archs: [ x86_64 ]
allowable-clients: [ vecLib ]
symbols: [ _quadrature_integrate ]
...

Framework:-

The framework is a package that can contain resources such as nib files, headers files, image files, etc. With small changes to its structure, it can even contain other frameworks. such aggregate is known as the Umbrella framework

Frameworks intended for the same purpose as static and dynamic shared libraries. But unlike libraries, frameworks:

  • can include resources like images, assets, documentations, strig files.
  • only one copy of framework read-only resource-loaded to memory, that allows decreasing memory footprint and share framework between iOS app and extensions. 

Frameworks supported from iOS 8.

Talking about frameworks also worth mentioning umbrella frameworks and universal frameworks (fat frameworks) :

Umbrella Framework: is a framework bundle that contains other frameworks. Umbrella frameworks available for macOS apps, but Apple does not recommend using them. Umbrella frameworks are not supported on iOS,watchOS, or tvOS.

Universal Framework (fat framework): multi-architecture binary that contains code native to multiple instructions sets and can run on multiple processor types. In short, it contains code compiled for all the platforms which you are going to support. For example, x86_64 (64-bit simulator), arm64, arm64e, armv7, armv7s for devices. As a result, such a framework will have a larger size than a one-architecture framework. There are lots of tutorials on how to make a universal framework using lipo.

This approach widely used for sharing a private binary. In this way, your framework consumer able to work with your framework on a real device and simulator.

Apple says that the app on average contains 100-400 system .dylibs. The loading of the system framework is highly optimized, But loading custom embedded frameworks can be expensive, Apple's engineers encourage you to use frameworks wisely and limit the amount of the used framework because it impacts the app launch time. If you are interested in deep details on how the framework works and how it impacts the app launch time, check the WWDC session Optimizing App Startup Time.

Last year Apple declare that Swift 5 provides binary compatibility for apps, which means that the app builds with one version of the Swift compiler will be able to talk to a library built with another version. Swift's ABI is currently declared stable for Swift 5 on Apple platforms.

Summary:-

I hope you came eager to distributes your awesome idea, this article will help you to pick your choice between library and framework which is best to distribute your idea in between teams or public.


Comments

Popular posts from this blog

Which is the best way to distribute Custom Framework?

So You have a solution to a problem that many other iOS developers have and you want to help them, but you also want to protect your code and build a business? Binary Framework. That's what you want! You might have noticed that you can't see the source code of UIKit Framework you use to build your iOS apps on top of every day. That's because Apple ships the UIKit as a binary framework in its iOS SDK. Below are the available ways of creating Libraries or framework:-  Umbrella Framework:   In the Apple development environment, the  incorporation  of one framework into another is called “ Umbrella ”. This type of framework is meant to hide the use of some sub-frameworks and thus facilitate their use.   Umbrella frameworks available for macOS apps , but Apple does not recommend using them. Apple does not officially support the Umbrella Frameworks for  iOS,watchOS, or tvOS , indeed citing the official documentation: Don't create Umbrella Frameworks. While it is...

What is the defer statement and what is the use of defer statement?

Defer Statement: Introduced in Swift 2.0, The Swift Defer statement isn't something you'll need to use often.  What is Defer? A defer statement is used for executing code just before transferring program control outside of the scope that the defer statement appears in. In simple words, defer is an operator used with closure where you include a piece of code that is supposed to be executed at the very end of the current scope. Syntax defer { statements } Example func f () { defer { print ( "defer statement executed" ) } print ( "End of function" ) } f () // Prints "End of function" // Prints "defer statement executed" The above example defer statement was executed after the print statement after the end of function f() 's Scope. Multiple Defer One of the most powerful features of defer statement is that you can stack up multiple deferred pieces of work, and Swift will ensure they all get executed. If you use multiple de...