Cocoapodsをより使いこなすためのTips

こんにちは[@huin](https://twitter.com/huin)です.

さてみなさん、[Cocoapods](http://beta.cocoapods.org/)をどれくらい使っていますか？

今ではコレなしのiOS(Mac)アプリ開発は考えられないくらいに必須のツールとなったCocoapodsですが、
対応していないライブラリも当然ながら存在します.

自分で書いたちょっとしたライブラリはもちろん、広告SDKなどは対応していないことが多いですね.

毎回ソースを自分のプロジェクトにコピーして...とやってもいいのですが、
どうせならこういったライブラリ群もCocoapodsでまとめて管理したいですよね？

というわけで、この記事ではCocoapodsに対応していないライブラリを自分で対応させるためのtipsを紹介します.

**注意**  

- Cocoapodsのバージョンは執筆時点の最新版である`0.28.0`を仮定しています.
- ライブラリのバージョン管理にはgitを使用しており、githubでホスティングされているものとします.

**目次**

1. 自作ライブラリを管理する
2. githubで公開されているライブラリを管理する
3. ソースが公開されていないライブラリを管理する

## <a name="1-manage-my-library"></a>1. 自作ライブラリを管理する

自作ライブラリの場合は簡単です. 
podspecファイルを作成して自分のリポジトリに追加してやればいいのです.

まずは podspec ファイルを作りましょう.

```bash
$ cd /path/to/MyLibrary
$ pod spec create MyLibrary
```

`MyLibrary.podspec`というファイルが作られるので、これを編集します.
ファイルの中に各項目の説明が書いてあるのでそれを参考にしながら編集していけばOKです.

より詳しい書き方については [ドキュメント](http://guides.cocoapods.org/making/specs-and-specs-repo.html)を参考にしてください.

このとき、`s.version`と`s.source`の部分を以下のように書いておきます.

```rb
Pod::Spec.new do |s|
	# s.versionで指定したバージョンを、s.sourceの　:tag　で呼び出すように書いておく.
	s.version = "0.0.1"
	s.source  = { :git => "https://github.com/username/MyLibrary.git", :tag => "#{s.version}" }
end
```

編集が終わったら、`git tag -a 0.0.1 -m 'first release'`のようにtag付けを行った上でgithubにpushします.
こうしておくことでライブラリのバージョンを指定して利用することが簡単になります.

githubにpushができたらあとは、ライブラリを使う側のプロジェクトで`Podfile`を書くだけです.

```
pod 'MyLibrary', :git => 'https://github.com/username/MyLibrary.git', :tag => '0.0.1'
```

という風にリポジトリも指定してあげましょう.
このとき, `:tag => '0.0.1'`とタグを指定してやればバージョンを指定して入れることができます. ([参考](http://guides.cocoapods.org/syntax/podspec.html#source))

## <a name="2-manage-open-source-library"></a>2. githubで公開されているライブラリを管理する

ソースコードはgithubで公開されているがpodspecファイルが用意されていないライブラリ、たまーにありますね.
この場合はどこにpodspecを置くかが問題となります. 

1. podspecを書いてPullRequestを送る
2. forkして自分のリポジトリに持ってきてpodspecを書く.
3. gistにpodspecを置いてそれを参照する.

イチバンかっこいいのは1.の方法ですね. なんかあまりメンテナンスされていない気がするなら2. の方法で自分でメンテしてあげるのもアリです. いずれにしてもこれらの方法であれば上に書いた自作ライブラリの方法がつかえます.

1.と2.どちらもちょっと...という場合はgist上にpodspecを書いてしまいましょう.
MyLibrary.podspecというファイル名でgistを書いたら、rawリンクをコピーしておきます.

Podfileは以下のように書きます.

```rb
pod 'MyLibrary', :podspec => 'https://gist.github.com/username/abc...xyz/raw/abc...xyz/MyLibrary.podspec'
```

これでgitst上のpodspecを参照してよろしくインストールしてくれます. ([参考](http://guides.cocoapods.org/syntax/podfile.html#pod))

## <a name="3-manage-proprietary-library"></a>3. ソースが公開されていないライブラリを管理する

広告SDKなどソースコードが公開されておらず、
コンパイル済みバイナリ(.aファイル)とヘッダーがzipでまとめて配布されている、
そんなパターンもよくあります. 

この場合はどうすればいいでしょう？

自作ライブラリのように、
リポジトリを用意して自分のzipを展開したファイルと自分で書いたpodspecを置いてやる...というのもできますが、
(プライベートならまだしも)公開リポジトリに置くのはライセンス的に抵抗があります.

実はCocoapodsではソースの指定にはgit以外にもsubversion, mercurial, httpでのDLが指定できます. 
もしzipファイルのダウンロードリンクがわかっているのであれば、
httpでファイルをDLした後、これを展開してやればいいのです.

```
Pod::Spec.new do |s|
    # zipファイルのURLと、`:flatten => true`を指定する.
    s.source  = { :http => "https://example.com/path/to/AnySDK.zip", :flatten => true }

    # ヘッダーファイルを指定する.
    s.source_files  = 'AnySDK/**/*.h'
    
    # コンパイル済みバイナリを指定する.
    s.preserve_paths  = 'AnySDK/**/*.a'
    
    # ヘッダーパスを指定しておくとコード補完などしてくれて便利.
    s.xcconfig  = { 'LIBRARY_SEARCH_PATHS' => '"$(PODS_ROOT)/AnySDK/**"' }
end
```

`s.source` のところで httpを指定した上で `:flatten => true`オプションをつけること、
コンパイル済みバイナリを `s.preserve_paths`で指定するところがポイントになります.

このファイルをgistにアップするなどして参照すればこれまでと同様`pod install`で導入できるようになります.

もし、zipファイルのDLすらわからない場合はどうすればいいでしょう？
(試してはいませんが)DropboxにファイルをアップしておきそのDLリンクを使用することでいけるはずです.

## まとめ

というわけで、マスターリポジトリに用意されていないライブラリもCocoapodsで管理するためのtipsを紹介しました.
毎回ファイルをコピーして...という煩雑な作業はやめてこれからはすべてのライブラリをCocoapodsで管理しましょう.

※ 誤った記述などあればコメントから指摘していただければと思います.

## おまけ

podspecを作成する再、毎回gistのファイル書き換えたりしているとすごく手間です.
正常に導入できるようになるまでは、ライブラリを導入するPodfileに

```
pod 'AnySDK', :podspec => './local/path/to/AnySDK.podspec'
```

のようにローカルのpodspecファイルを指定しておき、編集を繰り返しながら作成すると良いです.
(複数のプロジェクトで使いまわすという意味ではローカルファイルは不便なのでおまけとしました)