20211011のiOSに関する記事は1件です。

iOSアプリ開発のための外部ライブラリのリンクの種類や配布/利用方法

はじめに iOSアプリ開発用パッケージマネージャーごとのStatic/Dynamicリンク設定とカスタマイズおよび各種調査方法について整理したのですが、スタティックとかダイナミックリンクってなんなのよ、ということもあるので、その前提知識としてiOSアプリ開発のための外部ライブラリのリンクの種類や配布/利用方法についても整理しておきます。 この記事では大きく分けて下記の2つのことを説明します 外部ライブラリのリンク種類 スタティックリンク ダイナミックリンク 外部ライブラリの配布/利用方法 Library Framework XCFramework そしてこれは例えば、"スタティックリンクのFramework"や"ダイナミックリンクのFramwork"の組み合わせが存在するということです。 用語としてややこしいのは外部ライブラリの配布方法にLibraryとFrameworkがあることです。この記事では外部ライブラリと書いた場合、スタティック/ダイナミック関係なくLibrary/Frameworkの区別はしません。具体的には外部ライブラリ-> SVProgressHUD みたいなノリです。 私自身が勘違いしている可能性も高いし、もっといいまとめ方もあるかもしれないのでそれはそれでコメントか別にアウトプットしてもらえればありがたいです。 外部ライブラリリンクの種類 Appleの昔のドキュメントから 主にOSX用のドキュメントですが、スタティックリンクについて下記のように図示されています。 上記、重要なのはApplication codeの中にStatic librariesが含まれるということ。逆に下記で示されるダイナミックリンクではApplication codeにはDynamic library refrencesを含み、そのライブラリの実体はアプリとは別ファイルとして保持します。 上記Appleドキュメントを読むと、「ダイナミックリンクのライブラリは本体アプリサイズを抑える」 ことなどの解決策として存在するのがわかります。これは例えばUIがあるアプリはUIKit.frameworkとかをiOS側に持っておけば各アプリはそれを参照さえすればいいわけです。iOS 13からのSwiftUI.frameworkでもそうでしょう。iOS 13からiOS側でSwiftUIのフレームワークを持っているからiOS 13からSwiftUIを使える。 しかしiOSアプリとして我々がアプリ利用者に配布する際は外部ライブラリをダイナミックリンクとしても利用者がダウンロードする全体のアプリサイズは外部ライブラリを含んでいるので上記のドキュメントの 「ダイナミックリンクのライブラリは本体アプリサイズを抑える」 記述はしっくりくる理由にはなっていないのがわかります。 macOSでAtom.appを覗いてみる ダイナミックリンクのライブラリについて想像しやすくするため、macOSのAtom.appの中を見てみます。 libffmpet.dylibやlibnode.dylibなどが同梱されており、これがダイナミックリンクされている、ということでしょう。iOSアプリに限らず、ダイナミックリンクのライブラリを同梱するのであればAtom.appのサイズは大きいのでこれ良い具体例ではないかもしれませんがニュアンスわかるでしょうか。これらのダイナミックリンクライブラリがmacOSにあってそこを参照するならたしかにアプリサイズはその分だけ小さくて済むはずです。 2つのリンク手段 外部ライブラリリンクの種類としてダイナミックとスタティックあるので2つの概要を整理します ダイナミックリンクライブラリ 概要 必要なときにロードする アプリの起動時またはランタイムにロードすることができる iOSアプリだと起動時になるのは? Dynamicローダ 起動時にアプリが実際に使用する外部シンボルのみを解決 別名 Dynamic Shared Libraries shared objects Dynamically Lindked Libraries メリット アプリのファイルサイズとメモリフットプリントの削減 動作 Heap領域にDynamic Library Refrencesを持つ Dynamic Libraryのファイル自体は別途保持 スタティックリンクライブラリ 概要 スタティックリンカーを使ってリンクするとライブラリが実行ファイルにコピーされる スタティックリンカー オブジェクトコードを実行時に全体をメモリにロードする オブジェクトコードとは コンパイル済みのソースコードとライブラリコード 別名 Static archive Libraries Statick Lindked Shared Libraries 動作 アプリ起動時にアプリ自体のコードとリンクされているStaticライブラリのコードを含めてアドレス空間に読み込まれる ヒープ領域でアプリ自体と一つのファイルになっている(.appに組み込まれている) 混乱しそうなのはスタティックリンクは起動時に時間かかりそうだけど、ビルドの後半でスタティックリンカーによって、アプリと一体になっているからアプリ起動時間にダイナミックリンクに比べたら遅くなる要因は少ない ライブラリ配布/利用手段 Library 外部ライブラリリンクの種類 スタティックリンク ダイナミックリンク 実体 ビルド済みのソースコード Framework 外部ライブラリリンクの種類 スタティックリンク ダイナミックリンク 実体 ビルド済みのソースコード、画像リソース、ローカライズされた文字列、ヘッダー、リファレンス 例 Foundation.framework UIKit.framework SwiftUI.framework XCFramework 実体 複数CPUアーキテクチャ別のFrameworkを1つにまとめたもの 経緯 だいたいの経緯がわかってると、なぜこんな種類があるのかなんとなくわかるはずですので書いてみます。 2014 Xcode 6でiOS 8からダイナミックリンクのFrameworkをサポートした おそらく ダイナミックリンクのLibraryも同時にサポートされた? もともとはセキュリティ上の懸念があってできなかった? iOS 8からAppのExtensionが導入されたため懸念を払拭してやらざるを得なくなった? Embedded Frameworkもだいたいこのあたり 2015 Xcode 7でiOS 9からBitcodeが対応 2019 Xcode 11(WWDC19)あたりでXCFrameworkが登場 Xcode 11からSwift Package ManagerがXcodeのGUIから設定できるようになった 2020 Swift Package ManagerでXCFramework形式の配布ができるようになった 2021 Carthage v0.37.0 --use-xcframeworksを使ってXCFramework化 CocoaPods v1.9.0 XCFramework対応 https://blog.cocoapods.org/CocoaPods-1.9.0-beta/ おわりに 冒頭で組み合わせとしてスタティックリンクされたFrameworkがある、と書いてはいますが、これ昔のAppleのFrameworkに関するドキュメントを見るとFrameworkの説明としてダイナミックリンクの説明とそのメリットについて述べています。つまり、スタティックリンクなFrameworkは昔は存在しなかったのかなと思います。なぜならFrameworkのLibraryに比べたメリットはリソースを持てることだからですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む