Attention! Translated article might be found on my English blog.

2016年10月12日水曜日

.framework自作時のメモ

今回初めてframeworkを作ったので、その際の注意点をメモっておきます。

App Extensionで利用する際の配慮

AudioUnitやTodayなどのApp Extensionで利用する場合は[ターゲット名]-[General Info]-[Deployment Info]の"Allow app extension API only"にチェックを入れる。
チェックを入れないと、使用しているAPIに関わらず、フレームワーク利用側で
Linking against a dylib which is not safe for use in application extensions:
という警告が出てしまう。

参考: CocoaPods0.36をExtensionで使うときに出る警告を抑制する - yashigani?.days

公開するヘッダ

公開するヘッダは[ターゲット名]-[General]-[Headers]のPublicに入れておく。
と同時に、ターゲット生成時に作られるヘッダ(フレームワーク名.h)に
公開するヘッダを#importで列挙しておく。
publicにしたヘッダで#importしているヘッダもpublicにする必要がある点に注意。

なお、HeadersのPublic, Private, Projectの違いは
Public: The interface is finalized and meant to be used by your product’s clients. A public header is included in the product as readable source code without restriction.
Private: The interface isn’t intended for your clients or it’s in early stages of development. A private header is included in the product, but it’s marked “private”. Thus the symbols are visible to all clients, but clients should understand that they're not supposed to use them.
Project: The interface is for use only by implementation files in the current project. A project header is not included in the target, except in object code. The symbols are not visible to clients at all, only to you.
とのこと。

参考: XCode: Copy Headers: Public vs. Private vs. Project? - Stack Overflow

アーカイブされる場所

ArchiveするとビルドはされるがOrganizerは表示されないし、
どこにビルドされたのかよく分からない。
自分の場合はどうやら
~/Library/Developer/Xcode/DerivedData/[フレームワーク名-ランダム文字列]/Build/Intermediates/ArchiveIntermediates/SYFW/IntermediateBuildFilesPath/UninstalledProducts/macosx/
にフレームワークが生成されているようだったが、
IntermediatesとかUninstalledとか書いてるので
本当にここを参照して良いのかは分からない…。
どの環境変数で参照できるかは後日調べる。

クライアント側で使用する場合

ざっくり

  1. .frameworkファイルをプロジェクトへ追加
  2. フレームワーク埋め込み設定
  3. フレームワーク検索用パスを設定

が必要。

1:  .frameworkファイルをプロジェクトへ追加

通常のソースファイルと同様に.frameworkファイル(ディレクトリ)をプロジェクトへ追加する。

2: フレームワーク埋め込み設定

[ターゲット名]-[Build Phases]にて"+"ボタンを押下する。
"New Copy Files Phase"を選択する。
名前は適当に"Embed Frameworks"辺りにする。
"Destination"を"Frameworks"にする。
下部の"+"ボタンを押下しフレームワークを追加する。

3: フレームワーク検索用パスを設定

[ターゲット名]-[Build Settings]にて"framework search paths"で検索する
(フィルタはAll, Combinedが良さげ)
"Framework Search Paths" にフレームワークを内包するディレクトリを指定する。
(.frameworkそのものを指定してはいけない)


ちなみに、フレームワークを埋め込まなくても
~/Library/Frameworks, /Library/Frameworks/ /System/Library/Frameworks辺りに
フレームワークがあればリンクしてくれる。


-- 追記 --

古いプロジェクトに組み込む場合、Runpath Search Pathsに@loader_path/../Frameworksを追加する必要があるかもしれません。

参考: Library not loaded エラー?ここを見直そう - Qiita