CocoaPodを使ってアプリを
疎結合・再利用可能にする方法

Toru Hosokawa
twitter:@anton0825
facebook:toru.hosokawa1
github:hosokawa0825
blog:http://d.hatena.ne.jp/anton0825/

2014.3.9

Objective-Cでコードを書いてて
困ること

  • アプリを構造化するための機能が弱い
    • Packageスコープが無い
    • 名前空間を分けられない
  • コードの再利用が難しい
    • 一つのクラスを別のプロジェクトで使おうとしたら、依存しているクラスが沢山あってそれもコピーしないと使えない

解決策:CocoaPod

アプリのコードを複数のPodライブラリに分割し、CocoaPodを使ってその依存関係を解決する。

自社用Podライブラリ作成手順

  • Specsリポジトリを作る
  • Specsリポジトリからライブラリをインストール可能にする
    pod repo add private git@github.org:username/specs.git
  • Specsリポジトリにpodspecファイルを置く。配置ルールは「ライブラリ名/バージョン番号/ライブラリ名.podspec」
    例:Specs/MyLib/0.0.1/MyLib.podspec

メリット

  • コードの再利用が簡単になる
    →pod installを実行するだけでコードを再利用出来るようになる。
    複数のアプリで使用しているコードに不具合修正を入れた場合も修正箇所は一箇所で良くなる。

メリット

  • Packageスコープのメソッドを定義できる。
    やり方:
    • ヘッダファイルをスコープに合わせて以下に分割する。
      *_Public.h, *_Package.h
    • podspec内でpublic_header_filesを使って*_Public.hのみ公開する。
      s.public_header_files = 'MyLib/Classes/**/*_Public.h'
    これによってライブラリのメソッドのほとんどを隠蔽することができ、ライブラリの使いやすさや堅牢性が上がる。

メリット

  • パッケージ毎にPrefixを分けることで名前空間を分けられる。
    例:AFNetworkingの「AF」
    名前空間を分けることで、
    名前の衝突をあまり気にしないでよくなり、
    クラス名をシンプルにすることが出来る。
    例:DetailedStockForOrderTableViewController →SSTStockTableViewController

メリット

  • 依存関係を強制できるので、アプリの結合度が下がる。
    例えば、モデルクラスをまとめて一つのPodにすれば
    モデルがビューやコントローラに依存しないことを保障できる。

メリット

  • サブアプリ単位でアプリのバージョンを切り替えられる。
    例えば、サブアプリ1のバージョンAとサブアプリ2のバージョンBを組み合わせてみるとか。
    ABテストの実施がより簡単になる。
  • xcodeprojファイルのコンフリクトが減る。

デメリット

  • 以下をライブラリの数だけ作らないといけない
    • XCodeのプロジェクト
    • JenkinsなどのCI

    XCodeのプロジェクトの作成・設定の自動化をするcrafterというツールがあるので、これを使うと多少楽になりそう(未検証)

デメリット

  • ライブラリの修正をアプリに取り込むのが面倒
    通常の手順:
    • 新バージョンのタグを切る。0.1.5とか
    • 新バージョン用のpodspecを作り、Pushする
    • ローカルでpod updateを実行する

    これはPodfileで以下のようにbranch指定でインストールすることである程度解決出来る。
    pod 'AFNetworking', :git => 'https://github.com/AFNetworking/AFNetworking', :branch => 'master'

デメリット

  • Podfileでインストールするライブラリが依存しているライブラリは必ず最新版をインストールするようには出来ない。

デメリット

  • branch指定でインストールした場合、
    pod updateを実行するタイミングによってライブラリのバージョンが異なる。
    さらに、現在ローカルにあるのはどのバージョンかを知ることが出来ない。
  • 依存しているすべてのPodのmasterの更新を見張っておき、
    更新されたら自動でダウンロードしてくれる仕組みが欲しい・・・
    やり方知ってる人いたら共有お願いします!

最後に・・・

弊社(シンプレクス株式会社)ではiOSエンジニアを募集しています!
転職・派遣契約どちらでもOK。
弊社は金融系のiOSアプリを作っています。
求めるスキル:UIKitを使ったアプリの開発経験
(Cocos2D、PhoneGap等を使わない素のネイティブアプリ)
興味があれば御連絡下さい
@anton0825