作ったライブラリをCocoaPods/Carthageでimportする

ios

CocoaPods

長らく使われている依存ライブラリ管理ツール。

$ sudo gem install cocoapods
$ pod --version
1.9.1

podspec

まずはライブラリ側の作業。podspecを埋めていく。 Trunkに上げないPodに依存する場合、spec.dependency では :git:path を指定できないので、アプリ側のPodfileで指定する。

$ ls
SampleFramework			SampleFramework.xcodeproj	SampleFrameworkTests

$ pod spec create SampleFrameworkSambaiz

Specification created at SampleFrameworkSambaiz.podspec

$ cat SampleFrameworkSambaiz.podspec 
Pod::Spec.new do |spec|
  spec.name             = 'SampleFrameworkSambaiz'
  spec.version          = '0.0.2'
  spec.license          = { :type => 'MIT', :file => 'LICENSE' }
  spec.homepage         = 'https://github.com/sambaiz/ios-sample-framework'
  spec.authors          = { 'Taiki Sakamoto' => '[email protected]' }
  spec.summary          = 'Sample Framework'
  spec.description      = <<-DESC
                            This 
                            is 
                            a sample framework
                          DESC
  spec.source           = { :git => 'https://github.com/sambaiz/ios-sample-framework.git', :tag => 'v0.0.2' }
  spec.source_files = 'SampleFramework/**/*.{h,m,swift}'
  spec.requires_arc     = true
  spec.ios.deployment_target = '9.0'
  spec.swift_version = '4.0'

  spec.frameworks       = ['CFNetwork'] # A list of system frameworks that the user’s target needs to link against.
  spec.weak_frameworks  = ['Twitter'] # A list of frameworks that the user’s target needs to weakly link against.
  spec.vendored_frameworks = ['path/SomeFramework.framework'] # The paths of the framework bundles that come shipped with the Pod.
  spec.dependency 'SomeOtherPod'
end

$ pod spec lint

SampleFrameworkSambaiz.podspec passed validation.

subspecに分割すると一部だけインストールできる。

spec.default_subspecs = 'All'

spec.subspec 'All' do |sdk|
  sdk.dependency              'SampleFrameworkSambaiz/Foo'
  sdk.dependency              'SampleFrameworkSambaiz/Bar'
end

spec.subspec 'Foo' do |core|
  core.source_files         = 'SampleFramework/Foo/**/*.{h,m,swift}'
end

spec.subspec 'Bar' do |core|
  core.source_files         = 'SampleFramework/Bar/**/*.{h,m,swift}'
end

trunk

publishする。

$ pod trunk register godgourd@gmail.com 'Taiki Sakamoto' --description='mbp'
[!] Please verify the session by clicking the link in the verification email that has been sent to [email protected]

$ pod trunk me
  - Name:     Taiki Sakamoto
  - Email:    [email protected]
  - Since:    March 27th, 16:02
  - Pods:     None
  - Sessions:
    - March 27th, 16:02 - August 2nd, 16:04. IP: xxx.xxx.xxx.xxx Description: test

pushするとCocoaPods/Specにpodspecが上がる。

$ pod trunk push SampleFrameworkSambaiz.podspec

import

アプリ側の作業。Podfileを書いていく。

$ pod init
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Podfile

$ vi Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SampleApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SampleApp
  pod 'SampleFrameworkSambaiz/Foo',  '0.0.3'

  target 'SampleAppTests' do
    # Pods for testing
  end

end

なお、trunkではなく直接Gitリポジトリを参照したり、ローカルのpodspecを参照することもできる。

pod 'SampleFrameworkSambaiz/Foo', :git => 'https://github.com/sambaiz/ios-sample-framework.git', :branch => 'develop'
pod 'SampleFrameworkSambaiz2/Bar', :path => './ios-sample-framework2'

pushしただけではローカルに反映されていないのでupdateしてからinstallする。

$ pod repo update
Updating spec repo `trunk`

$ pod install
$ tree ~/.cocoapods/repos/trunk/Specs/f/5/4/SampleFrameworkSambaiz
/Users/sambaiz/.cocoapods/repos/trunk/Specs/f/5/4/SampleFrameworkSambaiz
├── 0.0.3
│   ├── SampleFrameworkSambaiz.podspec.json
│   └── SampleFrameworkSambaiz.podspec.json.etag
└── 0.0.4
    ├── SampleFrameworkSambaiz.podspec.json
    └── SampleFrameworkSambaiz.podspec.json.etag

Podsディレクトリとxcworkspaceができている。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   SampleApp.xcodeproj/project.pbxproj

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Podfile
	Podfile.lock
	Pods/
	SampleApp.xcworkspace/

$ tree Pods/SampleFrameworkSambaiz
Pods/SampleFrameworkSambaiz
├── LICENSE
└── SampleFramework
    └── Foo
        └── Foo.swift

xcworkspaceを開くと元々のアプリとPodsのprojectが入っていて、 依存frameworkにPodsのものが追加されているのでそのままimportできるようになっている。

xcworkspaceの構成

通常、アプリのビルド時にPodsの方もビルドするのでライブラリのサイズによっては時間がかかってしまう。 これを解消するにはcocoapods-binaryPre-compilingするか Carthageを使う。

Carthage

後発の依存ライブラリ管理ツール。ハンニバルのカルタゴであるが、カーセッジと発音する人もいる。 update時にframeworkをビルドするのでアプリケーションのビルドが遅くならず、workspaceを生成せず依存も触らないので挙動がシンプル。

$ brew install carthage
$ carthage version
0.34.0

ライブラリ側はManaged SchemasのSharedにチェックを入れるだけ。

import

Cartfileを書いてupdateする。CocoaPodsのtrunkのようなものは存在せず、直接リポジトリを参照する。 updateするとBuildディレクトリにframeworkができるのでこれを依存に入れればimportできる。

$ cat Cartfile
github "sambaiz/ios-sample-framework" >= 0.0.4

$ carthage update
*** Fetching ios-sample-framework
*** Checking out ios-sample-framework at "v0.0.5"
*** xcodebuild output can be found in /var/folders/1x/bzw0n3ss6_j0t7nlphn2cjrm7ngzh2/T/carthage-xcodebuild.Owsxl9.log
*** Building scheme "SampleFramework" in SampleFramework.xcodeproj

$ tree -L 3 Carthage/
Carthage/
├── Build
│   └── iOS
│       ├── 33F1736C-D538-3EE2-9BF7-86004B596A9B.bcsymbolmap
│       ├── SampleFramework.framework
│       └── SampleFramework.framework.dSYM
└── Checkouts
    └── ios-sample-framework
        ├── LICENSE
        ├── SampleFramework
        ├── SampleFramework.xcodeproj
        ├── SampleFrameworkSambaiz.podspec
        └── SampleFrameworkTests

あとはBuild PhasesのScriptに carthage copy-frameworks を入れる。 これは提出用アプリにシミュレーター用のバイナリが含まれないようにするためらしい。

参考

Carthageについて知りたいn個のこと