CocoaPods 集成和使用
一、iOS和OSX中添加第三方依赖库
- CocoaPods 和 Carthage 作为 iOS 和 OS X 下的第三方库管理工具,通过 CocoaPods 和 Carthage 可以方便的为项目添加第三方依赖库。方便管理其版本的同时,也大大的提高了开发效率。下文中仅以 Cocoapods 为主介绍其环境集成和使用。
1.1 CocoaPods介绍
- CocoaPods 作为一个提供中心仓库的第三方库管理工具,可以方便的添加第三方库的依赖并自动完成对第三方库的配置。利用 CocoaPods 还可以集成自己发布的开源库和创建的私有库。
- CocoaPods 添加第三方依赖库时,会自动创建一个新的workspace,主项目添加的所有依赖库都放在自动创建的Pods项目中,让主项目依赖Pods项目。
1.2 Carthage介绍
- Carthage 是一个去中心化的第三方库管理工具。相对于 CocoaPods 来说,Carthage 使用更加简单。
- Carthage 管理第三方依赖库时,不会过多的入侵主项目的项目结构,添加依赖完成的项目相对 CocoaPods 比较干净。添加的依赖库会自动编译为Dynamic framework。
- 可以与通过 CocoaPods 添加依赖的项目无缝对接。
- Carthage iOS8+。
1.3 CocoaPods 和 Carthage 优缺点
- CocoaPods
- 优点:
- 第三方库丰富
- 工具功能丰富、完善
- 缺点:
- 需要更新中心仓库(这里说的仓库,不是github上所有托管库的代码库的集合,而是github上托管的所有开源仓库的索引集合),并且每次更新需要连接中心仓库比较耗时
- 发布第三方库到 CocoaPods 操作繁琐
- 对主工程项目结构入侵较多
- 优点:
- Carthage
- 优点:
- 去中心化,使用时只需要更新具体的库
- 直接加载 framework 编译耗时短
- 不改变主工程项目结构
- 缺点:
- 第三方库有限
- 仅支持iOS8+
- 工具功能不完善
- 无法再主工程中直接查看第三方库源码
- 优点:
二、CocoaPods环境集成和使用
2.1 配置 ruby 环境
- 通常ruby源默认为https://rubygems.org/,由于众所周知的原因,我们需要将ruby源改为国内的源站。
-
gem sources –l
// 查看ruby源 -
gem sources --remove https://rubygems.org/
// 删除ruby源 -
gem sources -a https://gems.ruby-china.org/
// 添加ruby源
-
- 注:国内ruby源由于淘宝源(https://ruby.taobao.org/)已经不再维护,推荐使用https://gems.ruby-china.org/
2.2 安装 CocoaPods
-
安装 CocoaPods 之前,如果 gem 版本太老,需要升级gem:
- 更新gem
sudo gem update --system
- 查看gem版本
gem -v
- 更新gem
-
安装 CocoaPods
-
sudo gem install cocoapods
// 安装或更新 -
pod setup
// 在~/.cocoapods/repos中创建一个目录用来保存spec-repos,并从https://github.com/CocoaPods/Specs拉取Specs到本地,如果~/.cocoapods/repos目录已经存在,则会将当前目录下的仓库更新到最新版本。 -
报错1:
- 对于执行安装过程中的报错,这里如果报Operation not permitted - /usr/bin/xcodeproj。
- 解决方案:
sudo gem install -n /usr/local/bin cocoapods
pod setup
-
报错2:
- pod setup 失败
- 解决方案1:删除master重新下载
pod repo remove master
pod setup
- 解决方案2:
- 直接从github上clone或者下载一个Specs到本地,重命名为master,拷贝到~/.cocoapods/repos目录下
- 再次执行
pod setup
验证
-
-
更新 CocoaPods
sudo gem install cocoapods
-
卸载或者版本回退 CocoaPods
sudo gem uninstall cocoapods
-
版本查看
pod --version
-
备注:近期升级系统 MacOs High Sierra,遇到cocoapods无法更新repo的问题,提示各种权限和无法更新的问题,初步确认问题在ruby环境,故需升级ruby,但通过
sudo gem update --system
无法更新ruby,最终的解决办法,安装rvm,通过rvm安装新版本ruby,再安装cocoapods即可。
2.3 给项目添加 CocoaPods 库依赖
-
方式1:执行
$ pod init
-
方式2:直接创建文件
-
1.在主项目根目录创建一个Podfile文件(命名注意:Podfile)
-
2.编辑Podfile文件格式和内容:<Podfile文件的编辑可以选择CocoaPods App>
platform:ios, '8.0' // 指定要添加依赖的主工程的运行平台,适配的最低版本 target 'YourApp' do // 指定要添加依赖的target pod 'AFNetworking', '3.0.1' // 添加需要依赖的库,可以通过pod search来搜索github上托管的第三方库 end
-
注:编辑完成注意保存
-
说明:关于指定pod versions
-
pod 'AFNetworking'
// 省略版本号,即总是希望使用最新的版本作为依赖 -
pod 'AFNetworking', '3.0.1'
// 指定特定版本号,即总是使用指定的特定版本作为依赖 -
pod 'AFNetworking', '> 3.0.0'
// 指定高于3.0.0的任意版本,即总是使用高于3.0.0的任意版本作为依赖 -
pod 'AFNetworking', '>= 3.0.0'
// 指定3.0.0或者高于3.0.0的任意版本,即总是使用3.0.0或者高于3.0.0的任意版本作为依赖 -
pod 'AFNetworking', '< 3.0.0'
// 指定任意低于3.0.0的版本,即总是使用低于3.0.0的版本作为依赖 -
pod 'AFNetworking', '<= 3.0.0'
// 指定3.0.0版本和任意低于3.0.0的版本,即总是使用3.0.0版本或者低于3.0.0的版本作为依赖 -
pod 'AFNetworking', '~> 3.0.1'
// 指定版本3.0.1及其之后版本中低于3.1.0(不包括3.1.0)的版本 -
pod 'AFNetworking', '~> 3.1'
// 指定版本3.1及其之后版本中低于4.0(不包括4.0)的版本 -
pod 'AFNetworking', '~> 0'
// 指定版本0及其之后版本中低于1.0的版本
以上关于版本指定,除了指定特定版本这种方式外,其他指定版本的方式都是在满足当前约束条件下默认使用的约束条件下的最大版本作为依赖
-
-
除了以上指定版本之外,还可以指定pod的master分支作为依赖版本(指定具体版本的方式好处是指定的版本一般都是tag版本,是第三方库作者测试通过的可发布的版本,而指定master作为依赖时,有可能其中的部分代码还在测试和完善阶段的作者没有发布的源代码,即tag之外的代码,选择master作为依赖版本要慎重。选择master作为依赖一般用在团队开发的私有库的 开发模式 中,或者自己维护的开源库 开发模式 中,开发完成后切换到tag版。)
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git'
-
-
3.通过
pod search
来搜索需要依赖的库pod search AFNetworking
-
4.从本地加载依赖库
-
5.添加依赖到主工程
-
pod install
// 下载Podfile中的所有依赖库,并在./Pods路径下创建一个Pods库工程 -
pod update
// 更新依赖库,如果指定依赖库可以更新具体的第三方依赖库,否则更新所有需要更新的依赖库。 - 注:二选一
-
-
补充
-
pod update 在执行的时候每次都会先执行pod repo update,比较耗时,所以一般选择不更新本地仓库使用
pod update --no-repo-update
-
当github上托管的第三方库有更新版本时,需要更新本地仓库:
-
pod repo update
// 不指定具体仓库,会自动更新所有仓库
或者
-
pod repo update master
// 指定更新master
-
-
同时给多个target添加依赖库的,例如TestTarget / AppExtensionTarget,只需要在Podfile文件中添加多个target.
platform:ios, '8.0' target 'YourApp' do // add lib end target 'YourTestTarget' do // add lib end
-
2.4 解除项目 CocoaPods 依赖
- 删除本地文件:
- podfile
- podfile.lock
- pods文件夹
- 删除工程文件:
- xcworkspace
- 删除项目中的frameworks文件夹下面,pods.xcconfig和libpods.a文件
- 进入target,在build phases中,删除copy pods resources/Embed pods frameworks/check pods manifest.lock三项
- 删除工程中对第三方库的引用
三、发布项目到CocoaPods
- 很多时候,我们会自己造轮子,如果想托管到github作为第三方库在 CocoaPods 中使用,就需要发布项目到 CocoaPods
- 在组件化等项目架构的使用方式中,会需要用到不方便开源的私有库,如果想通过 CocoaPods 方便的集成和管理,就需要通过 CocoaPods 创建私有库
3.1 发布开源库到 CocoaPods
- 发布开源库到 CocoaPods 不止一种方式,这里通过Pod trunk的方式发布开源库到 CocoaPods
说明:使用pod trunk 发布项目到cocoapods需要cocoapods版本高于0.33
1.第三方库代码
- 编写要开源的第三方库的代码,完成测试和bug修复。
2.github创建仓库
- 创建一个和项目名同名的github仓库。
3.clone github上的仓库到本地
- clone 新创建的仓库到本地。clone的项目一般会包含LICENSE和README.md文件
4.Xcode创建项目
- 将编写完成的开源库代码文件以文件夹的形式(文件夹一般以开源库命名)放在clone路径中。
- 开源库一般提供一个示例工程,在colne路径中,创建一个新的xcode项目,一般以demo或者example的方式。并在demo或者example项目的根目录中引用编写完成的第三方开源库文件(注:由于开源库已经在当前路径中了,所以xcode项目引用的时候不要勾选copy it if need)。
- 编写README.md
5.创建podspec 文件
$ cd clone根目录
$ pod spec create hellohud
- 打开生成的podspec文件,此处为hellohud.podspec文件
- podspec编辑参考
- 注:不要用系统的编辑器打开,因为如果直接用系统的编辑器打开的话编辑过程中会对符号自动转换编码,而导致podspec文件验证通不过。
Pod::Spec.new do |s|
s.name = "hellohud"
s.version = "0.0.1"
s.summary = "A state bar hud for iOS on window"
s.homepage = "https://github.com/username/HelloWindowHud"
s.license = "MIT"
s.author = { "username" => "username@163.com" }
s.source = { :git => "https://github.com/username/HelloWindowHud.git", :tag => s.version }
s.source_files = "HelloWindowHud/"
s.requires_arc = true
s.platform = :ios, "7.0"
end
-
使用#注释掉不需要的选项
-
注:podspec中的内容填写有比较严格审查制度,如果规则错误会导致podspec文件无法使用。
- name 第三方库的名称
- version 第三方库的版本(tag)
- summary 第三方库的摘要
- homepage 第三方库的首页
- license 第三方库使用的license
- author 第三方库的作者
- source 第三方库的git版本库
- source__files 第三方库的的source_file文件位置
- requires_arc 是否要求arc
- platform 第三方库支持的平台
- 除了上述基本信息外,还可以指定当前库需要依赖的其他库,如果当前库依赖的库为第三方库,需要是已经发布的第三方库
-
注:
- 1.每个第三方库支持的平台不同,所以如果不是支持全平台的第三方库,在platform部分需要做platform说明。
- 2.source_files 要找对位置,这个极为重要。一般情况下,clone路径下面会包含如下文件:
- LICENSE
- README.md
- DEMO/EXAMPLE
- 第三方库
这种情况,source_files就是 'github上的仓库名/'
6.commit项目到github
- 将已经添加了.podspec文件的项目commit。
7.给项目打一个tag
$ cd clone路径
$ git tag -a '0.0.1' -m 'tag release 0.01'
$ git push --tags
$ git tag // 查看所有的tag
$ git tag -d 0.0.1 // 删除对应的tag
8.验证podspec文件是否符合要求
$ pod spec lint HelloWindowHud.podspec // 联网
$ pod lib lint // 不联网
- 报错:
-
echo "2.3" > .swift-version
.- 解决:直接运行
$ echo "2.3" > .swift-version
- 解决:直接运行
-
9.注册pod trunk
/**
* @param email 用户邮箱
* @param username 用户名
* @param description 设备描述
*/
$ pod trunk register email 'username' --description='device description'
// pod trunk register emailemail@163.com hellohud
查看账户信息
$ pod trunk me
10.podspec验证没有报错,则发布
$ pod trunk push HelloWindowHud.podspec
- 报错:
- 对于1.2.0版本的 CocoaPods 会导致无法发布podspec而报错
- 解决:升级 CocoaPods 1.2.1
参考CocoaPods issue6697
- 解决:升级 CocoaPods 1.2.1
- 对于1.2.0版本的 CocoaPods 会导致无法发布podspec而报错
11.第一次发布需要去认领podspec
- 新项目第一发布需要认领。
- 认领时,输入cocoapods的username 、 email 以及认领的第三方库名字即可。
- 认领成功的同时,即表示发布成功。
更新pod 搜索自己的第三方库即可
$ pod repo update
$ pod search CodePush
- 注:在做搜索之前最好清一下cocoapods的缓存,否则会搜不到最新发布的库
$ rm ~/Library/Caches/CocoaPods/search_index.json
- 最后执行
pod search
- [挖坑填坑:上述操作中5、6、7顺序不能换]
3.2 利用 CocoaPods 创建私有库
1.创建私有库git仓库(托管私有库源码) & 创建私有spec仓库(和CocoaPods的podspec仓库相同)
2.将私有 spec 仓库添加到 CocoaPods
$ pod repo add [spec仓库名] [私有spec仓库地址]
- 查看clone到本地的私有spec仓库
~/.cocoapods/repos
3.创建私有库及编辑podspec文件和校验,参考 CocoaPods 发布开源库中的操作 1 - 9 完全相同
-
注意:
- 做spec文件校验的时候,由于我们要创建的是私有库,除了开启访问权限的成员外,任何人无法直接访问,这种情况会有警告
- WARN | url: The URL () is not reachable.
,避免警告的操作 pod spec lint CodeLog.podspec --private
或者
pod spec lint CodeLog.podspec --allow-warnings
- 做spec文件校验的时候,由于我们要创建的是私有库,除了开启访问权限的成员外,任何人无法直接访问,这种情况会有警告
4.将私有库的pospec文件提交到私有 spec 仓库
-
cd 私有代码库clone路径
// 目的是可以拿到其中的.podspec文件 -
$ pod repo push [spec仓库名] [私有库.podspec文件]
// 将.podspec文件提交到私有spec仓库, 当遇到有警告而导致的验证失败时,可以后面加--allow-warnings参数避免警告 -
提交完成,执行pod search验证即可。
5.集成私有库
- 如果 Podfile 中不指定 source 的地址,则默认github的specs地址,但私有库的spec地址为自己创建的私有 spec 地址,所以包含私有库的 Podfile 文件要指定私有库podspec文件的私有 spec 仓库地址。如果指定 source 的地址并且主工程同时包含开源库和私有库,则需要同时指定私有spec地址和CocoaPods的spec地址,这样在添加依赖库的时候会同时从私有 specs 地址和 CocoaPods 的 specs 地址添加。
source 'https://github.com/CocoaPods/Specs.git'
source 'http://git.oschina.net/username/CodeSpec.git'
source 'https://github.com/CocoaPods/Specs.git'
source 'http://git.oschina.net/username/CodeSpec.git'
platform:ios, '8.0'
target 'demo' do
// 私有库
// github托管的开源库
end
备注:
- 私有库引用私有库,验证podspec,需加上私有库的spec地址
pod lib lint --sources='https://github.com/CocoaPods/Specs.git,私有spec仓库地址' // 本地验证
pod spec lint --sources='https://github.com/CocoaPods/Specs.git,私有spec仓库地址' // 远程验证,也可以加上--allow-warnings去掉警告
- 利用podSpec文件将库文件分为不同的虚拟文件夹,方便对功能或者类文件进行针对性的分类
s.subspec 'ClassA' do |classa|
classa.source_files = 'tt/Classes/ClassA/*'
end
分类后的虚拟文件夹为ClassA,其文件来源在路径tt/Classes/ClassA/*中
-
私有库更新:
- 对于不需要新增tag的情况,需删除原git仓库中的tag,然后创建相同的tag上传,这种方式,在私有库更新完使用时,需要清空cocoapods缓存
pod repo update 私有spec仓库名
// 更新私有仓库spec
pod cache list
// 查看cocoapods 缓存
pod cache clean 私有库名字
// 清除对应私有库的缓存
Podfile中,去掉对私有库的依赖,然后pod update
Podfile中,添加对私有库的依赖,然后pod update
- 对于新增tag的情况,直接新增tag即可
pod repo push [spec仓库名] [私有库.spec]
- 对于不需要新增tag的情况,需删除原git仓库中的tag,然后创建相同的tag上传,这种方式,在私有库更新完使用时,需要清空cocoapods缓存
-
【报错】[!] An unexpected version directory
Classes
was encountered for the/Users/name/.cocoapods/repos/gitee-yourname-test/test
Pod in thegitee-yourname-test
repository.- 解决方式:进入/Users/name/.cocoapods/repos/gitee-yourname-test,删除gitee-yourname-test文件夹就可以了