CocoaPodsとはターミナルからコマンドを打ってiOSやOS Xのライブラリを導入できるツール。
利用するライブラリのことをPodと読んでいるのでRubyGems≒CocoaPodsと考えるとわかりやすいかも。
CocoaPodsのインストール
OS Xに入っているRubyGemsを使ってセットアップできる。
( rbenvを使ってセットアップするメモ書きました http://qiita.com/items/53753cb824f47c4a48df )
sudo gem install cocoapods
pod setup
当然CocoaPods自体の更新もRubyGemsで行える。
sudo gem update cocoapods
Podの利用
Xcodeプロジェクトファイル(MyPorjectName.xcodeproj)と同じ階層で
platform :ios,'5.0'
pod 'JSONKit', '~> 1.4'
pod 'Reachability', '~> 3.0.0'
のようにファイル名Podfileというテキストファイルを置いてそのディレクトリでpod install
を実行するとPodが使えるようになる。その際に必要なframeworkやリンクオプションを追加して依存関係を解決してくれ、Xcodeプロジェクトの設定が変更され、Xcodeワークスペースが用意される。通常はCocoaPodsが作成してくれるXcodeワークスペースを利用するのが良い。
open MyPorjectName.xcworkspace
仕組みとしてはPod.aというスタティックライブラリプロジェクトをワークスペースに追加して、そこにソースファイルをまとめている模様。
どういうことを実際に行なっているかは Creating a project that uses CocoaPods にあるので自前のワークスペースに設定するときやうまく動かないときに参考になる。
[!] xxxx is not compatible with iOS 4.3.
とエラーがおきる場合は、以下のようにして明示的にiOSバージョンをPodfileに指定する必要がある。
platform :ios,'5.0'
ヘッダファイルはHeader Search Pathに"${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/JSONKit" のように追加されるのでimport "JSONKit.h"
import "JSONKit/JSONKit.h"
のどちらでも記述できるが後者の方が安全か。異なるPodでヘッダファイル名が重複した場合の動きは未調査。
リンクがうまくいかない場合などはPROJECTの方に設定が反映されているのでTARGETのOther Linker Flagsに$(inherited)が入っているかなどをチェックする必要がある。
Subspecの利用
PodによってはモジュールごとにSubspecという単位で分けている場合がある。例えばShareKitを使いたいけど全部はいらなくて特定のサービスだけ使いたいというときはPodfileを以下のように書ける。
pod 'ShareKit/Facebook'
pod 'ShareKit/Twitter'
CocoaPods 0.17.0からSubspecがMainSpecを継承しなくなったのでSubspecだけを使うときに依存するファイルが足りないことがある
CocoaPods利用時のリポジトリ構成
Bundlerの思想を受け継いでいるならPodfileとPodfile.lockだけリポジトリに入れておいて、他の開発者にはpod installでPodsディレクトリとワークスペースを作成してもらえばいいから、特にワークスペースの設定をいじっていないなら
Pods/
MyPorjectName.xcworkspace
でいいんじゃないかと思っているんだけどそれを裏付けるドキュメントはオフィシャルWikiからは見つけられなかった。
Podの作成
CocoaPodsにライブラリ定義の生成(pod spec create)や検証(pod spec lint)を行うコマンドが用意されている
pod spec create MyPod
vi MyPod.podspec
pod spec lint MyPod.podspec
書き方は仕様があるけど、既存Podのpodspecを見たりすると勉強になる。
ディレクトリ構成の推奨
https://github.com/CocoaPods/CocoaPods/wiki/Creating-and-maintaining-a-pod
.
├── Classes
└── ios
└── osx
├── Resources
├── Project
└── Podfile
├── LICENSE
├── Readme.markdown
└── NAME.podspec
ただこの形になっていないPodが多数存在する。(現状がPod以前のライブラリをかき集めている状態のせいかも)
個人的には以下のような構成にしてる。
MyPodName
├── MyPodName
└── {*.h,*.m}
├── MyPodNameDemo
├── MyPodNameDemo.xcodeproj
└── Podfile
└── MyPodName.podspec
デモプロジェクトからもPodを使って確認する。以下のようにpathオプションでPodを指定する。(MyPodName/MyPodNameDemo/PodfileからMyPodNameに依存)
CocoaPods 0.19からlocalオプションはpathオプションに名前変更#971
platform :ios,'5.0'
pod 'MyPodName', :path => '..'
なおPodfile、podspecファイルを編集する場合はエディタでRubyと認識させるといい。
ローカルで自分のPodを自分の複数のプロジェクトで共有する
再利用可能な自分のPodを複数のプロジェクトから参照する場合、相対パスだと面倒なのでどこかにPodプロジェクトをまとめるディレクトリを作って以下のようにすると参照しやすい。
pod 'MyPodName', :path => '~/code/Pods/MyPodName'
Podの配布
Pod公式リポジトリに公開しなくても
pod 'TTTFormatterKit', :git => 'https://github.com/gowalla/AFNetworking.git'
のようにしてSCM経由で利用してもらうこともできる。Forkしたライブラリを利用するときに有効。