声明:
- 最后更新时间:2019年3月18日
- 为保证时效性,持续更新地址为:Cocopods安装和使用
一、安装和使用Cocopods
网上已有很多教程,参考示例:CocoaPods安装教程
二、让自己的组件库支持pod方式引入
1.创建远程代码仓库
创建远程代码仓库(并不是podspec文件的仓库),此仓库放的是源代码。可以在GitHub上创建仓库。
2.创建远程specs仓库
如果要发布到Cocopods的官方specs仓库(公开的官方specs仓库),那么就不需要创建。当然私有库是需要创建的(创建方式和远程代码仓库一样,只不过specs放的是podspec文件),在这一步两者不一样。
公开库参考示例:发布开源库到Cocopods官方仓库
3.创建本地代码工程
可以使用pod命令创建,得到一个工程模板,并且可以根据需要配置工程,如下:
- 命令创建工程模板
pod lib create <组件库名>
- 工程配置选择
- 选择平台
What platform do you want to use?? [ iOS / macOS ]
iOS
- 选择语言
What language do you want to use?? [ Swift / ObjC ]
ObjC
- 是否自动生成一个用来做demo测试的模板库,建议Yes,后面方便测试
Would you like to include a demo application with your library? [ Yes / No ]
Yes
- 是否集成测试框架
Which testing frameworks will you use? [ Specta / Kiwi / None ]
None
- UI 测试
Would you like to do view based testing? [ Yes / No ]
No
- 指定类前缀
What is your class prefix?
WT
工程创建之后,就可以添加代码文件到组件库的class目录,图片资源到asset目录,不过要注意资源的引用方式是不是一个bundle(参考链接:资源文件)
4.编写podspec文件
如果用第三步的命令创建工程模板,那么在Podspec Metadata目录下已经自动生成了。如果是已有的工程或者库文件目录,也可以利用Pod命令自己制作.podspec文件,命令如下:
pod spec cretae <组件库名>
参考链接:
podspec文件的具体说明
注意:自动生成的podspec文件只是模板,需要结合工程的库文件、资源目录、远程代码仓库(第一步创建的远程代码仓库)修改补充podspec文件。
5.验证podspec文件
命令如下:
pod lib lint (从本地验证你的pod能否通过验证)
pod spec lint (从本地和远程验证你的pod能否通过验证,⚠️ 需要更新提交podspec到远程specs仓库,参考第8步,一般本地验证通过即可提交到远程specs仓库)
pod lib lint –verbose (加–verbose可以显示详细的检测过程,出错时会显示详细的错误信息)
pod lib lint –allow-warnings (允许警告,用来解决由于代码中存在警告导致不能通过校验的问题)
pod lib lint –sources=
https://git.xxx.com/windtersh… (私有库依赖需要添加specs源)pod lib lint –help (查看所有可选参数,可选参数可以加多个)
6.本地测试库是否可用
新建工程,切换到工程目录,执行命令
pod init
修改podfile文件, 并添加上本地库路径
pod '库名', :path => '/Users/xxx/Documents/库名'
- 拉取pod代码:成功后可看到我们的库并没有在pods里面,而是在Development Pods里面,可用先检测代码有没有问题。
7.提交工程代码
提交工程代码到远程代码仓库,可以利用git或者svn进行代码版本管理,提交代码到GitHub等, 初始化提交命令如下:
初始化git版本管理仓库,模板代码已经初始化了(有.git文件夹),此步骤可以忽略
git init
添加到暂存区
git add .
提交到本地仓库
git commit -a -m ‘Initial project’
打标签,注意此标签可能在podspec中用到,用于区分版本
git tag 0.0.1
本地仓库与远程仓库关联
git remote add origin <url>
拉取和合并本地与远程仓库
git pull origin master –allow-unrelated-histories
本地仓库代码推送到远程
git push –set-upstream origin master
推送标签
git push –tags
8.提交podspec文件
开源库提交podspec文件到Cocopods官方仓库, 当然需要现在ocopods官方仓库中注册账号,命令如下:
pod trunk me (检查是否注册trunk)
pod trunk register <邮箱> <注册名字> –verbose (注册命令)
注册完成之后会给你的邮箱发个邮件,进入邮箱邮件里面有个链接,需要点击确认一下.之后开始提交,切换到有.podspec文件的组件工程根目录执行命令
pod trunk push <组件库名>.podspec
pod trunk push <组件库名>.podspec –allow-warnings
- 私有库提交podspec文件到远程specs仓库(第二步创建的specs远程仓库),和Cocopods官方库不同的是,私有仓库需要先添加到本地仓库,再push到远程仓库,因为Cocopods默认已经添加到了本地仓库(默认为master),Mac系统可以查看文件目录(~/.cocoapods/repos), 私有库命令如下:
添加到本地仓库, git@git.xxxx/.git为远程specs库的地址,成功之后目录(~/.cocoapods/repos)除了master之外,新增了一个文件夹(<组件库名>)
pod repo add <specs仓库名> <specs远程仓库地址>
查看是否添加成功
pod repo list
push到远程specs仓库
pod repo push <specs远程仓库地址> <组件库名>.podspec
9. 检查仓库是否发布成功
pod搜索一下:
pod search <组件库名>
如果报错,搜索不到,建议更新下pod:
pod update
之后仍然搜索不到,那么进入CocoaPods缓存目录,删除缓存索引文件search_index.json:
cd ~/Library/Caches/CocoaPods
ls
rm -f search_index.json
10. pod库文件引入
如果是开源库(公有的),修改podfile文件:
pod '组件库名'
如果是私有仓库,建议在podfile文件开头添加source源:
source 'https://github.com/CocoaPods/Specs.git' #官方远程仓库地址
source ‘http://xxx/组件库.git’ #私有podspecs远程仓库地址
最后执行命令进行安装:
pod install
三、Cocoapods-packager插件打包库
1.静态库和动态库
文件形式:
- 常见形式:静态库常见的是 .a,动态库常见的是 .dll(windows),.dylib(mac),tbd(mac,Xcode7开始),so(linux)
- framework(Apple)形式: Framework 是Cocoa/Cocoa Touch程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件、说明文档等集中在一起,方便开发者使用。 framework其实是资源打包的方式,和静态库动态库的本质是没有关系。
静态库和动态库区别:
- 静态库:链接时会被完整的复制到可执行文件中,所以如果两个程序都用了某个静态库,那么每个二进制可执行文件里面其实都含有这份静态库的代码。
- 动态库: 链接时不复制,在程序启动后用dyld加载,然后再决议符号,所以理论上动态库只用存在一份,好多个程序都可以动态链接到这个动态库上面,达到了节省内存(不是磁盘是内存中只有一份动态库),还有另外一个好处,由于动态库并不绑定到可执行程序上,所以我们想升级这个动态库就很容易,windows和linux上面一般插件和模块机制都是这样实现的。注意:苹果开发中如果你把某个自己开发的动态库(系统的不算,毕竟苹果是爸爸)放在了Linked Frameworks and Libraries里面,程序一启动就会报Reason: Image Not Found,你只能把它放在Embeded Binaries里面才能正常使用。
- 静态库:一堆目标文件(.o/.obj)的打包体(并非二进制文件)。
- 动态库: 一个没有main函数的可执行文件。
静态库和动态库如何构建和加载
- 编译: 将我们的源代码文件编译为目标文件。
- 链接: 将我们的各种目标文件加上一些第三方库,和系统库链接为可执行文件。链接这一步最主要的操作就是决议符号的地址。若符号来自静态库(本质就是.o 的集合包)或 .o,将其纳入链接产物,并确定符号地址。若符号来自动态库,打个标记,等启动的时候再说—交给dyld去加载和链接符号。
- 加载:静态库启动时,动态库使用时(启动后。
静态库和动态库的依赖关系
- 静态库之间保持独立
- 可执文件(主程序或者动态库)在构建的链接阶段遇到静态库吸附进来(吸附性) ,遇到动态库打标记(彼此保持独立)。 注意:如果不想让动态库吸附静态库,可以把静态库包一层变成动态库。
查看Framework是否是动态库
在framework目录之下,如果带有dynamically标识着是动态库, 否则是静态库,运行命令file xxxx.framework
参考链接:iOS动态库和静态库分析
2.安装打包插件
通常可以通过Xcode(Xcodebuild)来打包静态库和动态库,现在通过Cocopods插件(脱离Xcode)来打包
直接通过gem命令安装
sudo gem install cocoapods-packager
找到 Gemfile文件,添加下面一行:
gem "cocoapods-packager"
然后运行命令
bundle install
2.打包库
运行打包命令,注意在podspec文件的目录下, 默认生成静态framework形式,并且类名和方法名会被加组件库的前缀避免冲突(比如:SDK引入AFNetworking,自己的项目中也引用 AFNetworking,SDK通过此种方式打包会被添加前缀,如:PodWTNetworking_AFURLSessionManager)
pod package xxxx.podspec
可以添加命令参数,运行一下命令查看
pod package –help
–force :强制覆盖之前已经生成过的二进制库
–no-mangle :不添加符号前缀(因为默认是添加前缀,避免冲突,如:PodWTNetworking_AFURLSessionManager)
–exclude-deps : 不包含依赖的符号表,生成动态库的时候不能包含这个命令,静态库一定需要包含依赖的符号表。
–embedded :生成静态.framework
–library : 生成静态.a(默认目录下只有.a,头文件需要自己整理)
–dynamic : 生成动态framework
–configuration=Debug :表示生成的库是debug还是release,默认是release
–spec-sources=
https://xxxxx.git,
https://github.com/CocoaPods/… :依赖库的远程specs,特别当依赖的库是私有仓库specs时需要添加示例:
pod package WTNetworking.podspec –spec-sources=
https://git.dev.tencent.com/w…://github.com/CocoaPods/Specs.git –force –library⚠️注意: 默认的符号添加前缀可能会造成问题:
- 参考另一个插件说明:cocoapods-mangle README.md,本人在测试的时候出现了问题,cocoapods-mangle插件直接处理AFNetworking就会报错中不到属性变量什么的(这个变量是id类型,并遵循某个协议),由于时间原因没有继续探究(本人当前主要探究一个App多个SDK都引用OpenSSL 造成冲突的问题,哪位大佬有好的方案请下方留言),但是打包插件cocoapods-packager确没什么问题(测试过程发现packager会给类和常量添加前缀,不会给分类方法添加前缀)。
- C语言格式的函数: 本人测试“AFQueryStringFromParameters”是可以的并不会冲突。
- 打包SDK依赖的时候,建议头文件的引用写在.m文件中,比如:SDK 引用了AFNetworking ,但是把【#import “AFNetworking.h”】 写在了.h文件中并在打包的时候暴露了出来,但是在项目中有没有直接用到AFNetworking,那么就会提示找不到AFNetworking。
四、Cocopods其它插件
参考链接:Cocopods插件安装及说明