実際のところ
便利な機能をインポートする目的や、処理の共通化の目的などでLibraryやFrameworkを使用したりするが、その違いを説明するのは難しい。
今回調べたので、記事にする。
違いを明確にしていく対象
- Library
- Framework
- Package
その前に 〜StaticとDynamicの違い〜
それぞれを比較する前に、
リンクの方式としてStatic Link(静的リンク)とDynamic Link(動的リンク)がある。
リンクとは?
プロジェクトのソースコードをコンパイルして生成されたオブジェクトファイルや外部ライブラリなどを全て連結(リンク)して実行ファイルまたは、ライブラリを生成する機能で、リンカ が行います。
ざっくり、アプリのような最終成果物を作るために必要な工程というイメージ。
StaticとDynamicの違い
- リンクされるタイミングの違い
- Static:ビルド時にリンクされる
- Dynamic:アプリ起動時にリンクされる
- アプリ内に含まれるかどうか
- Static:含まれる(バイナリコードがアプリ内に保持される)
- Dynamic:含まれない(バイナリコードへの参照がアプリ内に保持される)
App本体とWidgetなどのApp Extensionの両方などから参照される機能などは、Dynamic Link方式を採用することで、各アプリのファイルサイズを削減することができる。
詳しくは、iOSDC2019 ライブラリのインポートとリンクの仕組み… / Kishikawa Katsumi 参照
それぞれの違いについて
Library vs Framework
Bundleを持つか、持たないかの違い。
Bundleとは
Appleはバンドルを使って、アプリ、フレームワーク、プラグイン、その他多くの特定のタイプのコンテンツを表現します。
バンドルは含まれるリソースを明確に定義されたサブディレクトリに整理し、バンドル構造はプラットフォームやバンドルの種類によって異なります。
バンドルオブジェクトを使うことで、バンドルの構造を知らなくてもバンドルのリソースにアクセスすることができます。
ディレクトリを一つのファイルのように見せるもの。
決まった構成で作られるので、ヘッダーファイルや画像ファイルなどを含めることができる。
- Frameworkを使うメリット
- Bundleを持つことができるので、UIで使用する画像ファイルなども保持することができる
Package vs Others
Packageをここで並べるのは適切でないのかもしれないが、理解が混同していたため、ここに記載する。
- Packageのメリット
- 使用している依存関係を管理することができる
Package内から複数のLibraryやFrameworkなどを用いる場合に、それらのバージョンなどもSwiftファイルで簡単に管理できる。
一方、LibraryやFrameworkなどでそれらを実現したい場合は、独自にCocoaPodsなどを使用して、専用の依存関係を解決するファイルで管理する必要がある。
library(name:type:targets:)を使用して、リンク方式を指定することができる。
最後に
依存関係を整理するためにPackageを使用するのが、良さそうだが、
開発現場でSwift Package Managerを使用していなかったり、本当に少ない機能のみのコードを共通化したいとかであれば、FrameworkやLibraryの使用も検討してみても良さそうだ。
調べている途中に、WWDC2023のMeet mergeable libraries
というのに出会ったが、今回は力尽きたので、またの機会に。
軽く調べたところ、StaticとDynamicの良いところどりができるらしい。(ビルド時間とアプリの起動時間を共に短くすることができる)
めっちゃええやん。
参考
https://yamatooo.blog/entry/2020/10/03/083000
https://qiita.com/hironytic/items/3fcd825cc1ef135f5b0f
https://www.youtube.com/watch?time_continue=1070&v=FZoYyAEPJ8w&embeds_referring_euri=https%3A%2F%2Fzenn.dev%2F&feature=emb_title
https://medium.com/@zippicoder/libraries-frameworks-swift-packages-whats-the-difference-764f371444cd