CocoaPodsによる、外部ライブラリの利用と作成

2015.12.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CocoaPodsとは

CocoaPodsとは、定番のCocoaの依存管理マネージャーです。アプリ開発で煩雑となりがちな外部ライブラリの管理を、簡単な記述とコマンドだけ支援するものです。

002 https://cocoapods.org/

ざっくりと外観してしまうと・・・CocoaPodsは、Podfileに記述されたライブラリを、メタ情報をもとにダウンロードし、それらをまとめたPodsプロジェクトを生成します。 そして、ワークスペースの仕組みを利用して、既存のプロジェクトから、これを参照できるようにしています。

以下、動作について詳しく見ていきます。

2 インストール及び管理情報

(1) インストール

Macには、あらかじめRubyがインストールされているため、下記のコマンドでインストールできます。

$sudo gem update --system   <=ruby gemを最新にする
$sudo gem install cocoapods

(2) setupコマンド

setupコマンドで、github上のメタデータ(管理情報)「https://github.com/CocoaPods/Specs」が、ローカルの「~/.cocoapods」に展開されます。

$ pod setup

次の図は、setup実行後に「https://github.com/CocoaPods/Specs/tree/master/Specs」をブラウザで表示したものと、ローカルのディスクを一覧したものの比較です。

003

$ pwd
/Users/SIN/.cocoapods/repos/master/Specs
$ ls -la | head -n 15
total 0
drwxr-xr-x  14245 SIN  staff  484330 12 17 00:46 .
drwxr-xr-x      7 SIN  staff     238 11  5 11:05 ..
drwxr-xr-x     10 SIN  staff     340 12 16 02:54 120301
drwxr-xr-x      3 SIN  staff     102 12 16 02:54 1210
drwxr-xr-x      6 SIN  staff     204 12 16 02:54 12306DeveCocoa
drwxr-xr-x     22 SIN  staff     748 12 16 02:54 1PasswordExtension
drwxr-xr-x      4 SIN  staff     136 10  5 17:26 1PasswordExtensionHaha
drwxr-xr-x     14 SIN  staff     476 10  5 17:26 25519
drwxr-xr-x      4 SIN  staff     136 10  5 17:26 320Categories
drwxr-xr-x      3 SIN  staff     102 11  5 11:05 3DTouchHelper
drwxr-xr-x      6 SIN  staff     204 10  5 17:26 500px-iOS-api
drwxr-xr-x      3 SIN  staff     102 10  5 17:26 7blur
drwxr-xr-x      3 SIN  staff     102 10  5 17:26 A
drwxr-xr-x     14 SIN  staff     476 10  5 17:26 A2DynamicDelegate

それぞれのライブラリ名の中には、バージョン(実際にはgitのtag)名のフォルダとなっており、その中、下記のようなJSONファイル(ライブラリ名.podspec.json)が置かれいます。

次の図は、「Alamofire/3.1.3」の中の「Alamofire.podspec.json」を表示したものです。

004

podspec.json というファイルには、ライブラリの入手先(github)や、ビルド方法の定義が入ったメタデータとなっていることが確認できます。 CocoaPodsは、このファイルをもとに、ライブラリの管理を行っています。

なお、後述するinstallコマンドの実行時に、毎回ローカルの管理情報は更新されるため、setupコマンドをあまり意識する必要はないようです。

$ rm ーrf /Users/SIN/.cocoapods/repos/master <= 管理情報(masterフォルダ)の削除
$ pod install 
Creating shallow clone of spec repo `master` from `https://github.com/CocoaPods/Specs.git` <= masterフォルダの再構築
Updating local specs repositories

・・・省略・・・

(3) listコマンド

この管理情報の内容は、listコマンドで一覧することができます。 次の例は、Alamofireの情報を確認している様子ですが、「Alamofire」が利用可能なことと、最新バージョンが「3.1.3」であることが分かります。

※listコマンドは大量の出力があるためgrep等の併用をお勧めします。

$ pod list | grep Alamofire
  Alamofire 3.1.3
  Alamofire+Result 3.0.0-karumi
  Alamofire-Prephirences 1.0.1

・・・省略・・・

念のため、ファイルを確認してみると次のようになっています。

$ pwd
/Users/SIN/.cocoapods/repos/master/Specs/Alamofire
$ ls -al

・・・省略・・・

drwxr-xr-x      3 SIN  staff     102 12 17 02:18 3.1.1
drwxr-xr-x      3 SIN  staff     102 12 17 02:18 3.1.2
drwxr-xr-x      3 SIN  staff     102 12 17 02:18 3.1.3

listコマンドは、あくまでもローカルの情報を確認するコマンドであり、github上の最新情報を見るためのものではありません。

3 外部ライブラリの使用方法

最初に、既存のプロジェクトに外部のライブラリを組み込む要領について見ていきます。

(1) initコマンド

Xcodeプロジェクトのフォルダの中で、initコマンドを打つと、Podfileの雛形が生成されます。

$ pod init
$ cat Podfile 
# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
# use_frameworks!

target 'Sample001' do

end

(2) ライブラリ指定

この中に、取り込みたい外部ライブラリの情報を記載します。

次の例では、「Alamofire」を追加するように指定しています。

$ cat Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!

target 'Sample001' do
    pod 'Alamofire', '~> 3.0'
end

なお、ライブラリの指定方法ですが、単純に最新のバージョンを取得したい場合は、ライブラリ名だけを指定します。

    pod 'Alamofire'

そして、バージョンを指定したい場合は、その後ろにそれを記述します。

    pod 'Alamofire', '~> 3.0'

[バージョンの指定方法]

記述 意味
’1.0’ バージョン1.0を使用
’> 1.0’ 1.0 より上のバージョンを使用
’>= 1.0’ 1.0 以上のバージョンを使用
’< 1.0’ 1.0 未満のバージョンを使用
’<= 1.0’ 1.0 以下のバージョンを使用
’~> 0.1.2’ マイナーバージョン内での使用 0.1.2以降、0.2未満(すなわち0.1.2以降の0.1.x)
’~> 0.1'’ マイナーバージョン内での使用 0.1以降、1.0未満

ライブラリの取得先は、管理情報(メタデータ)に従わずに直接指定することも可能です。

ローカルのフォルダを指定する場合

pod 'AFNetworking', :path => '~/Documents/AFNetworking'

git上のmasterブランチを使用する場合

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'

git上の特定のブランチを使用する場合

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'

tagを指定する場合

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'

特定のコミットを使用する場合

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'

(3) installコマンド

Podfileの設定完了後、installコマンドでライブラリの取り込みが始まります。 (この時、xcodeでプロジェクトファイルを開いているとエラーが発生するという情報を見かけますが、現在は、特に問題ないようです。)

$pod install

installコマンドが実行されると、プロジェクトのフォルダ内に、Podfile.lock、ワークスペースファイル(.xcworkspace)、そしてPodsフォルダが作成されます。

$ ls -la
total 16
drwxr-xr-x   8 SIN  staff  272 12 17 03:11 .
drwxr-xr-x  28 SIN  staff  952 12 17 00:56 ..
-rw-r--r--   1 SIN  staff  208 12 17 01:59 Podfile
-rw-r--r--   1 SIN  staff  156 12 17 02:53 Podfile.lock <= lockファイル
drwxr-xr-x   8 SIN  staff  272 12 17 02:55 Pods <= 外部ライブラリがダウンロードされたフォルダ
drwxr-xr-x   8 SIN  staff  272 12 17 02:51 Sample001
drwxr-xr-x@  5 SIN  staff  170 12 17 01:59 Sample001.xcodeproj
drwxr-xr-x   4 SIN  staff  136 12 17 02:55 Sample001.xcworkspace <= ワークスペースファイル

Podfile.lockには、実際に取り込んだバージョンの情報が記載されています。

$ cat Podfile.lock 
PODS:
  - Alamofire (3.1.3)

DEPENDENCIES:
  - Alamofire (~> 3.0)

SPEC CHECKSUMS:
  Alamofire: 9f93b56389e48def9220dd57d1f44b1927229a5a

COCOAPODS: 0.39.0

Podsフォルダの中には、Podsというプロジェクトがあり、このプロジェクトが取り込んだライブラリと取りまとめ、ワークスペースの機能を利用して既存のプロジェクトから参照される仕組みになっています。

$ ls -la Pods
total 8
drwxr-xr-x  8 SIN  staff  272 12 17 02:55 .
drwxr-xr-x  8 SIN  staff  272 12 17 03:11 ..
drwxr-xr-x  5 SIN  staff  170 12 17 01:59 Alamofire
drwxr-xr-x  2 SIN  staff   68 12 17 02:55 Headers
drwxr-xr-x  2 SIN  staff   68 12 17 01:57 Local Podspecs
-rw-r--r--  1 SIN  staff  156 12 17 02:55 Manifest.lock
drwxr-xr-x  4 SIN  staff  136 12 17 02:55 Pods.xcodeproj
drwxr-xr-x  4 SIN  staff  136 12 17 02:55 Target Support Files

(4) updateコマンド

ライブラリの更新や、Podfileを編集した場合は、updateコマンドを使用します。

$ pod update

updateにより、Podfileから削除されたライブラリの削除も行われます。

(5) ワークスペースファイル

後は、installコマンドで生成されたワークスペースファイル(.xcworkspace)をXcodeから開いて作業を進めます。

$open Sample001.xcworkspace

Pods/Productsの中のフレームワーク名をimportすることで使用が可能になります。

006

(6)ワークスペース名の指定

installlコマンドでワークスペースが作成されますが、その名前は、既存のプロジェクト名と同じになります。しかし、既存のワークスペースに統合したい場合や、任意のワークスペース名を指定したい場合は、Podfileに「workspace 」の設定を追加します。

$ ls -la
total 0
drwxr-xr-x   5 SIN  staff   170 12 17 10:05 .
drwxr-xr-x  30 SIN  staff  1020 12 17 09:59 ..
drwxr-xr-x   4 SIN  staff   136 12 17 09:59 Origin.xcworkspace <= OriginワークスペースにSample001プロジェクトが含まれている
drwxr-xr-x   7 SIN  staff   238 12 17 09:59 Sample001
drwxr-xr-x@  5 SIN  staff   170 12 17 10:01 Sample001.xcodeproj

上記のようなOriginワークスペースに統合したい場合は、下記のように記述します。

$ cat Podfile
use_frameworks!

workspace 'Origin'

target 'Sample001' do
    pod 'Alamofire', '~> 3.0'
end

(7)use_frameworks!

Swift で書かれた Pods(ライブラリ)は、frameworks としてのみ統合できるとの事で、use_frameworks! の行のコメント(#)を外すことを忘れないでください。

001

(8) .gitignore

プロジェクトをgitで管理する場合、Podfileがあれば、Podsフォルダは、「pod install」で復活できるため、「Pods」を.gitignoreに記載して、Podsフォルダを管理外にすることができます。

しかし、この方法は、復活のためにCocoaPodsのインストールが必須となるなど、一概にメリットだけとは言えないので、それぞれの状況で検討が必要です。

なお、Podfile.lockも「pod install」で生成されますが、こちらは、実際に使用されているバージョンを管理しているものですので、管理外とすることはできません。

4 自作ライブラリの使用方法

次に、自ら作成したフレームワークをCocoaPodsで管理する要領について見ていきます。

手順として、「(1)ライブラリの作成」ー「(2)Demoプロジェクトの作成」という順になっている理由は、最終的に公開するトップのフォルダに、ライブラリのプロジェクトファイルが配置されるようにするためです。

(1) ライブラリの作成

Xcodeで「File」-「New」-「Project」とたどり「iOS」-「Framework & Library」 から「Cocoa Touch Framework」を選択し新しいプロジェクトを作成します。(ここでは、名前を「MyLib」としました)

011

続いて、「MyLib」の中にSwift Fileを追加します。(名前は、「MyLib.swift」としました)

012

MyLib.swiftには、ライブラリの機能として、次のような簡単なメソッドを1つだけ定義しました。

“MyLib.swift”

import Foundation

public class MyLib:NSObject{
    public class func start(){
        print("MyLib start..")
    }
}

(2) Demoプロジェクトの作成

続いて、動作を確認できるように、ライブラリを使用する側のプロジェクトとして「Demo」という名前のプロジェクトを作成します。

Xcodeで「File」-「New」-「Target」とたどり「iOS」-「Application」 から「Single View Application」を選択し新しいプロジェクトを作成します。(ここでは、名前を「Demo」としました)

013

この時点で、XcodeのProjectナビゲータでは、次のような配置になっています。

014

「Demo」プロジェクトから「MyLib」が参照できるように、「TARGETS」-「Demo」-「General」-「Embedded Binaries」に追加します。 015 「+」をクリックして表示されたダイアログでは、「MyLib.framewokriOS」を選択します。 016

追加が完了すると、次のようになります。

017

この時点で、Demoプロジェクトから利用が可能になっています。

018

ターゲットを「Demo」に変更して、シュミレーターで実行してみてください。(※当初「MyLib」でプロジェクトを作成したため、Demoに変更する必要があります)

019

起動時に「MyLib start..」が出力されることを確認できます。

020

(3) Githubでのリポジトリ作成

次にこのライブラリをGithub上に置くために、新しいリポジトリを作成します。

この時、ライセンスや、READMEのファイル作成もチェックしてgithubに雛形の生成をお願いしましょう。

021

なお、この時点でGithub上にリポジトリを作成する理由は、次に作成するpodspecファイルの「検証」で必要なためです。

(4) podspecファイル

CocoaPodsに管理させるためには、podspecファイル(メタ情報)が必要です。

MyLibのプロジェクトファイルが存在するフォルダで次のコマンドを打つと、podspecファイル(名前は、ライブラリ名.podspecとなります)の雛形が生成されます。

$ pod spec create MyLib
Specification created at MyLib.podspec
$ ls -la
total 16
drwxr-xr-x   6 SIN  staff   204 12 20 15:59 .
drwxr-xr-x  36 SIN  staff  1224 12 20 14:59 ..
drwxr-xr-x   7 SIN  staff   238 12 20 15:44 Demo
drwxr-xr-x   5 SIN  staff   170 12 20 15:04 MyLib
-rw-r--r--   1 SIN  staff  6123 12 20 15:59 MyLib.podspec <=作成された雛形
drwxr-xr-x   5 SIN  staff   170 12 20 15:41 MyLib.xcodeproj

後は、このファイルを編集しますが、今回編集した内容は次のとおりとなりました。

ライブラリの取得先は、先ほど作成したGithubになっています。

Pod::Spec.new do |s|
  s.name         = "MyLib"
  s.version      = "0.0.1"
  s.summary      = "MyLib"
  s.license      = { :type => 'MIT', :file => 'LICENSE' }
  s.homepage     = "https://github.com/furuya02/MyLib"
  s.author       = { "furuya02" => "sin@sapporoworks.ne.jp" }
  s.source       = { :git => "https://github.com/furuya02/MyLib.git", :tag => "#{s.version}" }
  s.platform     = :ios, '8.0'
  s.source_files = 'MyLib/**/*.{h,m,swift}'
end

podspecファイルの各項目の内容は次のようになっています。

名前 意味
name 名称
version バージョン
license ライセンス
summary 説明
homepage 公開URL
author 著作者情報
source ソースコード入手先
source_files ライブラリで実際に使用するファイルのパス

なお、詳しくは、公式のドキュメントをご参照ください。

編集が終了したら、チェックを行います。少し時間がかかりますが、「MyLib passed validation.」が表示されたらOKです。

下記の例では、LICENSEファイルがないという警告が表示されていますが、これは、Github上で先ほど雛形を生成したので、マージした時点で問題なくなります。

$ pod lib lint

 -> MyLib (0.0.1)

MyLib passed validation.

[!] Unable to read the license file `/Users/SIN/Documents/work/MyLib/LICENSE` for the spec `MyLib (0.0.1)`

(5) Githubへの公開

Githubへの公開は、次のとおりです。

$ git init  <=ローカルリポジトリの初期化
$ git pull https://github.com/furuya02/MyLib.git  <=Github上のファイルをpull
$ git add .  <= ローカルのファイルをステージングする
$ git commit -am "initialize"  <= コミット
$ git remote add origin https://github.com/furuya02/MyLib.git
$ git push  <= Githubへのpush
$ git tag 0.0.1  <= タグの追加
$ git push —tags  <= タグをGithubへのpush

マージが終了すると、Github上でtag「0.0.1」で現在の状態が取得できます。

022

(6) 使用してみる

それでは、今Github上に置いたライブラリを使用してみます。手順は「3 外部ライブラリの使用方法」のところで紹介した要領そのままです。

なお、Podfileの内容は、次のとおり。

use_frameworks!
target 'TestApp' do
    pod 'MyLib', :git => 'https://github.com/furuya02/MyLib.git'
end

また、installしている様子は、次のようになっています。

$ pod install
Updating local specs repositories
Analyzing dependencies
Pre-downloading: `MyLib` from `https://github.com/furuya02/MyLib.git`
Downloading dependencies
Installing MyLib (0.0.1)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `TestApp.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.

Podsプロジェクトの中に組み込まれた「MyLib」を利用できることを確認できます。

023

5 トラブル対処など

(1) 再インストール

CocoaPods自体の更新は、次のコマンドで可能です。

$ sudo gem update cocoapods

なお、再インストールは次のようになります。

$ sudo gem clean cocoapods <=古いバージョンを削除する場合
$ sudo gem uninstall cocoapods
$ sudo gem install cocoapods

(2) 管理情報の再設定

管理情報のフォルダを削除してしまって、setupコマンドで最新情報をダウンロードできます。

$ sudo rm ーfr ~/Library/Caches/CocoaPods/
$ sudo rm ーfr ~/.cocoapods/repos/master/
$ pod setup

(3) プロジェクト内での再構築

プロジェクト内では、Podsフォルダの中にすべての外部ライブラリが入っているので、これを削除して、updateコマンドを使用すると、Podfileの指定に基づいてライブラリが再構築されます。

プロジェクトフォルダに移動して
$ rm ーfr Pods/ 
$ pod update

(4)CocoaPodsをプロジェクトから削除する方法

Podfile、Podfile.lock、Pods、.xcsorkspaceを削除して、プロジェクトファイルから開きます。

$ rm Podfile
$ rm Podfile.lock 
$ rm ーrf Sample001.xcworkspace
$ rm ーrf Pods
$ ls -la
total 8
drwxr-xr-x   5 SIN  staff  170 12 17 04:00 .
drwxr-xr-x  28 SIN  staff  952 12 17 00:56 ..
-rw-r--r--   1 SIN  staff  208 12 17 01:59 Podfile
drwxr-xr-x   8 SIN  staff  272 12 17 03:28 Sample001
drwxr-xr-x@  5 SIN  staff  170 12 17 01:59 Sample001.xcodeproj
$ open Sample001.xcodeproj/

ツリーの中で、Pods等不要なファイルを削除します。

007

この時点でBuildすると、次のようなエラーが発生します。

008

Podfile.lockやManifest.lockとの連携を切るためには、「TARGETS」の「Build Phases」で次の2つを削除する必要があります。

  • Check Pods Manifest.lock
  • Copy Pods Resources

009

6 CocoaPodsのバージョンを統一する方法 [2015.12.22追記]

チーム開発などで、個々の利用しているCocoaPodsのバージョンに相違があって問題となることがあります。ここでは、バージョンを統一する要領について紹介します。

(1) グローバルのバージョン管理

グローバルにインストールされているCocoaPodsのバージョンを任意のものにするには、一旦削除して、バージョンを指定したインストール行うしかありません。

$ pod --version <= バージョンの確認
0.39.0
$ sudo gem uninstall cocoapods --version "=0.39.0" <=アンインストール
$ sudo gem install -v 0.38.2 cocoapods <=任意のバージョンのインストール
$ pod --version <= バージョンの確認
0.38.2

(2) ローカルのバージョン管理

Bundlerを使用すると、プロジェクト内にCocoaPodsの特定のバージョンを組み込むことができます。

Bundlerとは、Rubyのライブラリ管理ツールです。ここでは、Bundlerのセットアップが完了している前提で進めています。
参考:bundlerでgemをプロジェクトごとに管理する

$ cd project <= プロジェクトフォルダに移動
$ bundle init <= Gemfile(設定ファイル)の雛形作成
$ echo "gem 'cocoapods', '0.32.1'" >> Gemfile <= Gemfileにcocoapodのバージョン0.32.1を使用する指定追加する
$ cat Gemfile <= Gemfileの内容を確認する
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'cocoapods', '0.32.1'
$ bundle install --path vender/bundle <= プロジェクトの内(ローカル)にCocoaPodsがインストールされる
$ bundle exec pod --version <= プロジェクトの内(ローカル)のCocoaPodsを使用する
0.32.1
$ pod --version <= グローバルのCocoaPodsのバージョンは変化ない
0.39.0

7 まとめ

今回は、定番ツールであるCocoaPodsの利用方法について、外部ライブラリを「利用する立場」と、「作成する立場」の2つの方向でまとめてみました。

当初、「Swiftには対応していない」とのことでしたが、現時点では、全く問題なく利用できることを改めて確認できました。

8 参考リンク


iOSライブラリ管理の神ツール「CocoaPods」のインストールと使い方
stack overflow How to remove CocoaPods from a project?
Should I check the Pods directory into source control?
自前のライブラリをCocoaPodsで管理するメモ