流行のCocoaPods使ってみて、エラーになってはまった話(修正)

CocoaPodsを導入すると、iOS開発で使用するライブラリの導入管理が簡単になるとしって使ってみたんですが、いくつかはまったところがありました。

環境 

環境はこんな感じ

  • XCode 4.2.1
  • Mac OS X 10.7.2
  • MacRuby 0.10(RVM)
  • macgem 1.4.2
  • cocoapod 0.3.9

最初にはまったところ 

  1. 複数ターゲットでCocoaPodsで導入したライブラリを使用する場合、pod installをする前に必要なプロジェクトターゲットを作成する必要がある
  2. Header Search Pathが違う!! 一部のライブラリのヘッダファイルがHeadersディレクトリにシンボリックリンクされない!!
  3. テスト用static-libraryを作っても、デフォルト以外は自動でリンクはしてくれない
 
1. 複数ターゲットでCocoaPodsで導入したライブラリを使用する場合、pod installをする前に必要なプロジェクトターゲットを作成する必要がある
 

下のように、ターゲットが2つあるとして(アプリ用とテスト用)

後からターゲットを作成してしまうと、CocoaPodsでstatic-libraryがリンクされません。なので複数のターゲットを自動管理する場合は、pod installする前に必要なターゲットは作成しておくといいです。

f:id:zepbag:20120108164804j:plain

 2. Header Search Pathが違う!! 一部のライブラリのヘッダファイルがHeadersディレクトリにシンボリックリンクされない!!

*よく見たらHeadersディレクトリはありました!! なぜか全部のライブラリがコピーされない

:exclusive => trueでほかのtargetで指定したライブラリのシンボリックリンクが作られないのは、バグっぽいので修正してpull request送りました。(2012/01/09)

#104: fixed bug of directory cleaning. by roothybrid7 for CocoaPods/CocoaPods - Pull Request - GitHub

 > 上の暫定対策版をインストールできるようにしましたので、よろしければ、 CocoaPods 0.3.9 修正非公式版インストール — Gist からインストールしてみてください

 

3.のPodfileの記述に関係あるんですが、どうも targetブロックで:exclusive => trueを使ってしまうとtargetブロックの外で宣言しているライブラリのヘッダファイルがHeadersディレクトリにコピーされないみたいです。

 - targetブロックで:exclusive => trueを使った場合は、targetブロックの外のライブラリのヘッダファイルがコピーされない

platform :ios

dependency 'JSONKit', '~> 1.4'
dependency 'AFNetworking', '~> 0.7'
dependency 'BlocksKit', '~> 1.0'
dependency 'NSLogger'

# Testing framework for Test target.
target :test, :exclusive => true do
  dependency 'LRMocky'
end

f:id:zepbag:20120108190300j:plain

- targetブロックで:exclude => trueを使わなければ全部コピーされる

platform :ios

dependency 'JSONKit', '~> 1.4'
dependency 'AFNetworking', '~> 0.7'
dependency 'BlocksKit', '~> 1.0'
dependency 'NSLogger'

# Testing framework for Test target.
target :test do
  dependency 'LRMocky'
end

f:id:zepbag:20120108193304j:plain

 

ということで、今のところtest用に追加のライブラリだけをパッケージングするのは難しそうです。

3. テスト用static-libraryを作っても、デフォルト以外は自動でリンクはしてくれない

下記のように、Podfileを記述したとしてtargetブロックに囲まれた方のstatic-libraryは手動でリンクする必要があります。

最初、targetに指定する引数が、xcodeのプロジェクトターゲットと同じものだと思っていたのですが、全く関係ないらしいです。

よくある(:production, :develpment, :test)とおなじです。

CocoaPodsでは、下記の3つのシンボルが用意されています。(任意の文字列を使ってもいい) 

  • :default(targetブロックを使ってないところ)
  • :debug
  • :test
ちなみに、:exclusive => trueは targetブロックの外で宣言された dependencyのライブラリを含めないという意味です。
platform :ios

dependency 'JSONKit', '~> 1.4'
dependency 'AFNetworking', '~> 0.7'
dependency 'BlocksKit', '~> 1.0'
dependency 'NSLogger'

# Testing framework for Test target.
target :test, :exclusive => true do
  dependency 'OCMock'
  dependency 'LRMocky'
end

 

この構成だと下記の2つのstatic-libraryのターゲットを持つプロジェクトが生成されます。

  • libPods.a (デフォルト)
  • libPods-test.a (target :testで作ったやつ、ファイル名に指定した引数がsuffixとして付与される)
結局
 
targetブロックで:exclusive => trueをつけてしまうと、ブロック外で宣言しているヘッダファイルのシンボリックリンクが作られなくなるので、2.の:exclude => trueをつけない方で使用しようと思います。libPods.aとlibPods-test.aでライブラリが重複してしまいますが、アプリ用ターゲットには、デフォルトのlibPods.aを、テスト用ターゲットには、libPods-test.aをリンクして使用しようと思います。テスト用ターゲットにはライブラリが依存しているフレームワークの追加が必要になりますが。
 
 
まだ、手順やらドキュメント等が固まってない印象はありますが、いちいちダウンロードしてくるのにくらべればとても有益なツールだと思います。
 
 
参考