"Dynamic Frameworks" are often used interchangably with "Dynamic libraries". A common use case for dynamic frameworks is to share code between the main app binary and app extensions. This helps reduce the size of the overall app bundle being shipped. Other use cases include sharing system frameworks with the app, such as the Swift runtime libraries.
To demonstrate how dynamic frameworks can share code, we'll use the LinkedIn iOS app (version 2022.1201.1015) and examine its plugins.
Emerge Size Analysis X-Ray showing LinkedIn Plugins
X-Ray
BinariesLocalizationsFontsAsset CatalogsVideosCoreML Models
There are five plugins present:
- NotificationServiceExtension_extension
- ShareExtension_extension
- WVMPTodayExtension_extension
- NewsModuleExtension_extension
- ShareExtension_extension
Three of the app plugins are linking to the framework `VoyagerLibs` and can access all of its resources ‒ a good example of using dynamic frameworks to reduce code duplication.
On closer inspection, the plugin `NotificationServiceExtension_extension` has the 7.4 MB file `ArtDecoIconsResources.bundle`. `ArtDecoIconsResources.bundle` also exists in `VoyagerLibs`, but since `NotificationServiceExtension` doesn't link to `VoyagerLibs`, it must re-include the file. This is an oversight and an example where dynamic libraries should be used to reduce size.ArtDecoIconsResources (red) is uneccessarily duplicated in a plugin
Dynamic frameworks are a great resource for reducing the size of your app. It's important to note the runtime performance tradeoff with this approach, using too many dynamic frameworks can cause a regression in app launch time. You can read the Emerge glossary page for dyld to understand how dynamic frameworks are loaded.
Featured Analysis: Twitter 🧵 on how both the Twitter and Mastodon iOS apps could shave 20% off install size by utilizing dynamic frameworks.