####Cocoa 依赖管理
#####一、为什么要简化依赖管理?
手工管理依赖的缺点:麻烦、易出错、动作重复率高
#####二、CocoaPods 的安装和一般用法
1、CocoaPods 的优点
Cocoapods 本质上还是封装动态库静态库,但是它解决的最大问题就是依赖管理。
开发者不需要去手动下载代码,只需要定义一次,就能很容易的对第三方库进行下载整合和更新。
2、CocoaPods 的安装
2.1 更改 gem 源(绕墙)1
2
3$ gem sources --remove https://rubygems.org/
$ gem sources --add https://gems.ruby-china.org/
$ gem sources -l (查看 gem 源)
gems.ruby-china.org 是基于国内 CDN + 国外服务器的方式,能确保几乎无延迟的同步。
2.2 安装 cocoapods1
$ sudo gem install cocoapods // 可以通过此命令来更新 cocoapods
3、新建工程的 CocoaPods 的使用1
2
3
4
5$ cd 工程目录
$ pod init // 创建一个推荐的 Podfile
修改 Podfile 添加 pod 描述并保存
$ pod install
然后打开 .xcworkspace 文件来开发。
4、CocoaPods 的 关键文件
CocoaPods 通过一个 Podfile 来描述 target 的依赖关系。
所使用的 Pod 的版本号记录在 Podfile.lock 文件里。
这两个文件需要添加到 git 库
5、pod install 做了什么?
a) Podfile 中描述的 pod 如果可在 Podfile.lock 中找到,就下载 Podfile.lock 所具指的版本;
b) 如果在 Podfile.lock 中找不到,就寻找到Podfile 中所描述的版本,并解决依赖关系。
6、pod update 是干嘛的?
$ pod update [PODNAME]:忽视 Podfile.lock,将一个 pod 更新到尽可能新的版本
如果 PODNAME 不指定,意味着对每一个 Podfile 里的 pod 都做更新。
7、怎么知道哪些 pods 可以更新?1
$ pod outdated
8、CocoaPods 版本控制和依赖冲突
CocoaPods 使用语义化版本控制(Semantic Versioning)的命名约定。
版本号格式为:MAJOR.MINOR.PATCH
PATCH:修订号表示有实现细节的改变,比如 bug 的修复,向后兼容;
MINOR:次版本号表示有向后兼容的 API 的改变,比如新增了方法;
MAJOR:主版本号表示有不向后兼容的 API 的改变,更新后将破坏现有代码。
由于冲突解决系统建立在非重大变更的补丁版本之间,这使得解决依赖关系变得容易很多。例如,两个不同的 pods 依赖于 FMDB 的两个版本,假设一个依赖于 2.3.1,另一个依赖于 2.3.3,此时冲突解决系统可以使用最新的版本 2.3.3,因为这个可以向后与 2.3.1 兼容。
但这并不总是有效。有许多第三方库并不使用这样的约定,这让解决方案变得非常复杂。
当然,总会有一些冲突需要手动解决。如果一个库依赖于 FMDB 的 1.2.5,另外一个库则依赖于 2.3.1,那么只有最终用户通过明确指定使用某个版本来解决冲突。
9、Podfile
9.1 Podfile 示例
9.2 pod 语句的各种写法
9.2.1 pod ‘FMDB’
不指定版本号,尽量用最新版本
9.2.2 pod ‘FMDB’, ‘2.6.2’
具指版本号,只用指定版本
9.2.3 pod ‘FMDB’, ‘> 2.6.2’
使用大于 2.6.2 的尽可能新的版本
此外还可以使用 >=、<、<= 等逻辑操作符
9.2.4 pod ‘FMDB’, ‘~> a.b.c’
使用尽可能新的版本,该版本大于等于 a.b.c 但小于 a.(b+1).0, 即 [ a.b.c, a.(b+1).0 )
~> 为乐观操作符
‘~> 0’:写与不写一样
9.2.5 pod ‘FMDB’, ‘~> a.b’
使用尽可能新的版本,该版本大于等于 a.b 但小于 (a+1).0, 即 [ a.b, (a+1).0 )
4) 和 5) 即是说不进位。
9.2.6 pod ‘FMDB’, :git => ‘https://github.com/ccgus/fmdb.git‘
通过指定的 git 库的 master 分支安装 pod
9.2.7 pod ‘FMDB’, :git => ‘https://github.com/ccgus/fmdb.git‘, :branch => ‘dev’
通过指定的 git 库的 dev 分支安装 pod
9.2.8 pod ‘FMDB’, :git => ‘https://github.com/ccgus/fmdb.git‘, :tag => ‘2.6.2’
通过指定的 git 库的 2.6.2 tag 安装 pod
9.2.9 pod ‘FMDB’, :git => ‘https://github.com/ccgus/fmdb.git‘, :commit => ‘0f506b1c45’
通过指定的 git 库的 0f506b1c45 commit 安装 pod
9.2.10 pod ‘FMDB’, :subspecs => [‘FTS’, ‘SQLCipher’] 或 pod ‘FMDB/FTS’
安装指定的 pod subspecs
9.2.11 pod ‘FMDB’, :podspec => ‘https://github.com/ccgus/fmdb/blob/master/FMDB.podspec‘
通过指定的 podspec 安装 pod
9.2.12 pod ‘FMDB’, :path => ‘~/Framework/FMDB’
开发一个 pod 时指定 pod 的根目录,也是 podspec 文件所在目录
9.3 platform 的指定
platform :ios, ‘9.0’
platform 可以指定:osx :ios :tvos :watchos 四类
platform 的默认值是: :ios, ‘4.3’; :osx, ’10.6’; :tvos, ‘9.0’; :watchos, ‘2.0’; 将在未指定时生效。
9.4 source 的指定
只从官方源安装 pod 不需要指定 source。
多 source 时需要同时指定官方源,此时 sources 的先后顺序即查找顺序,查到后将不再查找其他 sources。
10、注意事项
1、已存在 workspace 的工程,在 Podfile 里需要添加语句:
workspace ‘已存在的 workspace’
2、Podfile.lock 文件冲突的一般处理策略是:忽略本地更改,然后 pod install
3、CocoaPods 可能会与 MacRuby 不兼容,若遭遇可以使用 rvm 安装 ruby
11、CocoaPods 插件
11.1 cocoapods-dependencies
安装
$ [sudo] gem install cocoapods-dependencies用法
$ pod dependencies [PODSPEC] [–image]
12、从工程中移除 pod1
$ pod deintegrate [XCODE_PROJECT]
13、卸载 CocoaPods1
$ sudo gem uninstall cocoapods
#####三、CocoaPods 的私有库
1、使用私有 spec 库
在 Podfile 里加两行即可使用:1
2source 'https://github.com/CocoaPods/Specs.git'
source 'REPO_SOURCE_URL'
2、建立自己的 pod
2.1 创建一个 Pod1
$ pod lib create POD_NAME
2.2 开发
2.3 编写 .podspec 文件
2.4 检查 pod
$ pod lib lint REPO_NAME
2.5 检查通过后,推送代码 和 tag 号1
2
3$ git tag '0.1.1'
$ git push --tags
$ git push
3、将 pod 推送到私有 spec 库
3.1 建立私有 spec 库
建立一个 git 库即可,需要有 master 分支
3.2 向 CocoaPods 添加/删除 私有 spec 库
$ pod repo add REPO_NAME REPO_SOURCE_URL
$ pod repo remove REPO_NAME
3.3 将 podspec 推送到私有 spec 库
$ pod repo push REPO_NAME SPEC_NAME.podspec
3.4 其他 repo 命令
$ pod repo lint REPO_NAME (检查 spec 库是否可用)
$ pod repo list (列举 spec 库)
$ pod repo update REPO_NAME (更新 spec 库)
4、 .podspec 文件中常用的语法
4.1 spec.cocoapods_version = ‘>= 0.36’
4.2 spec.ios.dependency ‘MBProgressHUD’, ‘~> 0.5’
4.3 spec.deprecated = true
spec.deprecated_in_favor_of = ‘NewMoreAwesomePod’
4.4 spec.weak_framework = ‘Twitter’
4.5 spec.source_files = ‘Classes//*.{h,m}’, ‘More_Classes//.{h,m}’
4.6 spec.public_header_files = ‘Headers/Public/.h’
spec.private_header_files = ‘Headers/Private/.h’
spec.exclude_files = ‘Classes/*/unused.{h,m}’
4.7 spec.ios.vendored_frameworks = ‘Frameworks/MyFramework.framework’
spec.ios.frameworks = ‘QuartzCore’, ‘CoreData’
4.8 spec.ios.vendored_libraries = ‘libProj4.a’, ‘libJavaScriptCore.a’
spec.ios.libraries = ‘xml2’, ‘z’
4.9 subspec
Pod::Spec.new do |s|
s.name = ‘AFNetworking’
s.subspec ‘Reachability’ do |ss|
ss.ios.deployment_target = ‘7.0’
end
end
#####四、Carthage 来了
1、Carthage 简介
CocoaPods 极大的简化了 Cocoa 的依赖管理,但由于采用了集中化管理的方式,所以对工程具有高侵入性,于是就有了另外一种去中心化、无侵入性的依赖管理方式——Carthage
Carthage 是地中海地区的古城,意为“新的城市”。
Carthage 打算成为向 Cocoa 应用添加 frameworks 的最简易的方式,它用一条命令将第三方库编译成 .framework(仅支持 iOS8 及以上版本),但是如何集成、如何设置依赖关系是由用户来实施的。
跟 CocoaPods 一样,Cartfile 和 Cartfile.resolved 两个文件都需要添加到项目的 git 库里。
Carthage 将第三方库自动打包成 framework,使得工程编译的时候用时更少。
对于拥有简单的依赖关系的第三方库来说,他们更适合用 Carthage 管理 。
Carthage 可以和 CocoaPods 共存。
2、Carthage 的基本工作流
2.1 创建 Cartfile ,列举需要的 frameworks
2.2 拉取并编译列举的每一个 framework
$ cathage bootstrap —platform ios
2.3 把编译后的 .framework 添加到 target 的 General / Linked Frameworks and Libraries 里(不需要 copy)
2.4 Build Phases + New Run Script Phase,添加 shell script
/usr/local/bin/carthage copy-frameworks
Input Files 添加:
$(SRCROOT)/Carthage/Build/iOS/f1.framework
$(SRCROOT)/Carthage/Build/iOS/f2.framework
……
2.5 添加/更新 framework1
2
3$ carthage update [FRAMEWORK_NAME] --platform ios
// e.g. $ carthage update AFNetworking --platform ios
$ carthage outdated
3、安装/更新 Carthage
安装方式1:下载 .pkg 文件安装
https://github.com/Carthage/Carthage/releases
安装方式2:brew install1
2$ brew update
$ brew install carthage
更新 Carthage:1
2$ carthage version
$ brew upgrade carthage
4、Cartfile 语法
格式: type URL version
type:github、git、binary
URL:github.com 可以缩略
version:
1) >= 1.0 for “at least version 1.0”
2) ~> 1.0 for “compatible with version 1.0”
3) == 1.0 for “exactly version 1.0”
4) branch / tag / commit,binary 格式不支持.
5) no version means any version of the dependency is allowed.
示例:
// # GitHub.com
github “ReactiveCocoa/ReactiveCocoa” ~> 1.1.0
// # GitHub Enterprise
github “https://enterprise.local/ghe/desktop/git-error-translations“
// # Git repositories
git “https://enterprise.local/desktop/git-error-translations2.git“
// # Binary only frameworks
binary “https://my.domain.com/release/MyFramework.json“
5、让自己的库支持 Carthage
5.1 建立 Cocoa Touch Framework
5.1.1 framework target / Build Phases / Compile Sources、Headers
5.1.2
如果你使用了类别,那么你需要在Build Settings的Linking的Other Linker Flags里加上-all_load
如果你想你的工程支持bitcode,需要在Other C Flags 里加上-fembed-bitcode
5.2 share schemes
Product / Schemes / Manage Schemes… / Shared
5.3 测试
5.3.1 $ carthage build –no-skip-current –platform ios
5.3.2 功能测试
5.4 测试通过后,推送代码 和 tag 号1
2
3$ git tag '0.1.1'
$ git push --tags
$ git push
6、从工程中移除 Carthage
把 Carthage/Build/iOS 留下
7、卸载 Carthage1
$ brew uninstall --force carthage
#####五、参考列表
1、语义化版本控制规范
http://semver.org
http://semver.org/lang/zh-CN/
2、CocoaPods 帮助页
https://guides.cocoapods.org
3、Carthage 主页
https://github.com/Carthage/Carthage#adding-frameworks-to-an-application
#####六、一切有为法、如梦幻泡影、如露亦如电、应作如是观。