Embedded Framework
Embedded Frameworkは平たく言うと、アプリのコードを分割してFrameworkとして利用する事ができる機能です。
XCode8からの機能なので話題としては古いのですが、丁度アプリのリファクタリングを行っている際に、Embedded Frameworkを用いたので記事として記載します。
Embedded Frameworkのメリット
Embedded Frameworkを導入する事で主に以下の恩恵を授かることができます。
差分コンパイルされる為、ビルドパフォーマンスが向上
よく語られるメリットです。
中規模以上のアプリですと、ビルドパフォーマンスが悪く、生産的ではありません。
劇的に…とまではいかないかもしれませんが、結構馬鹿にならないコスト軽減が見込めます。
WidgetやAppleWatch等、App Extentions間でコードを共有する事ができる
一応Targetを指定する事で、コード共有はできますが、Target指定の場合だと ファイルが複製され純粋に容量が増えます 。 なので、メインTarget以外でコードを共有する場合は、Embedded Frameworkをおすすめします。
依存関係が強制される為、後々の設計がきれいになる、依存を意識した製造を行える
製造中に気をつけることができれば、わざわざEmbedded Framework化しなくても良いのですが、気が緩むとどうしても綻びが生じ、気づいた頃にはリファクタリングに多大な時間を消費する事態を招きかねません。
なので、色々と人によってベストプラクティスは異なりますが、私としてはある程度まとまったモジュール単位でEmbedded Framework化してしまった方が良いと考えています。
テスタブルなコードが書きやすい
上記依存関係の話題に近い話ですが、やはり依存関係を意識した設計になるので、Embedded Frameworkを使わないケースと比べ、テスタブルなコード設計がやりやすい(その方向に製造をすすめることができると言いますか)です。
ただ、個人的にはアプリケーションの場合は、UTをCIに乗せるところにそこまで強い恩恵を感じていないため、UT事態をコアロジック部分くらいしか書かないので、強いメリットには感じていません(が、業務ロジックの場合だとそうも言っていられないので、やはりメリットですね)
Embedded Frameworkの導入方法
XCodeのFile -> New -> Targetから作成できます。
Framework & LibraryからCocoa Touch Frameworkを選択します。
その後、必要項目を入力する事で、新規にTargetが追加されます。
Embedded Frameworkの使い方
Targetが追加されたのと同時にProject Navigatorに該当グループができているので、その下にコードを追加していくだけです。
注意点としては、他モジュールからEmbedded Framework化されたモジュールへアクセスする場合は、publicでのアクセスになります。
(特にclass等にアクセス修飾子を指定シなかった場合はinternalになります)
Embedded FrameworkでCarthageを使う
Cartfieでinstallする所まではこれまでと同じなのですが、Embedded Framework内でしかCarthage経由でinstallしたライブラリを利用していなくても、メインTargetにも指定してあげる必要があります。
■メインTargetの設定例
Embedded FrameworkでCocoa Podsを使う
Carthageと同様に、Cocoa Podsの場合でもメインTarget、Embedded Framework共にライブラリのinstallが必要です。
特にこだわりが無ければabstract_targetにまとめるで良いでしょう。
abstract_target 'hoge' do pod 'Alamofire' # AlamofireとFirebaseがProjectUnknownTools Targetにinstall target 'ProjectUnknownTools' do pod 'Firebase/Core' end target 'API' do # AlamofireのみAPI Targetにinstall end end
Embedded Frameworkでの申請
Embedded Frameworkで申請するときに、以下のようなエラーが発生するかもしれません。
Code Signing Error: {Framework Name} has conflicting provisioning settings. ProjectUnknownCommon is automatically signed, but code signing identity iPhone Distribution: {Team Name} has been manually specified. Set the code signing identity value to "iPhone Developer" in the build settings editor, or switch to manual signing in the project editor.
この場合、Projectの設定で、
- Provisioning ProfileをAutomatic
- Code Signing IdentityのDebugを iOS Developer
- Code Signing IdentityのReleaseを iPhone Distribution
上記で設定すれば問題ないはずです。