声明:
- 最后更新时间:2020年7月23日
一、安装和使用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 ]
NoneUI 测试
Would you like to do view based testing? [ Yes / No ]
No指定类前缀
What is your class prefix?
WT
工程创建之后,就可以添加代码文件到组件库的class目录,图片资源到asset目录,不过要注意资源的引用方式是不是一个bundle(参考链接:资源文件1,资源文件2)
4.编写podspec文件
如果用第三步的命令创建工程模板,那么在Podspec Metadata目录下已经自动生成了。如果是已有的工程或者库文件目录,也可以利用Pod命令自己制作.podspec文件,命令如下:
pod spec cretae <组件库名>
参考链接:podspec文件的具体说明
注意:自动生成的podspec文件只是模板,需要结合工程的库文件、资源目录、远程代码仓库(第一步创建的远程代码仓库)修改补充podspec文件。
5.验证podspec文件
命令如下:
pod lib lint (从本地验证你的pod能否通过验证)
pod lib lint --help (查看所有可选参数,可选参数可以加多个)
pod lib lint --verbose (加--verbose可以显示详细的检测过程,出错时会显示详细的错误信息)
pod lib lint --allow-warnings (允许警告,用来解决由于代码中存在警告导致不能通过校验的问题)
pod lib lint --sources=xxxx.git,yyyy.git,https://github.com/CocoaPods/... (私有库依赖需要添加specs源,如果还依赖开源库需要添加官方源)
pod lib lint --sources=REPO_NAME1,REPO_NAME2,master(私有库依赖需要添加specs源, 如果还依赖开源库需要添加官方源)pod spec lint (从本地和远程验证你的pod能否通过验证,⚠️ 需要更新提交podspec到远程specs仓库,参考第8步,一般本地验证通过即可提交到远程specs仓库)
pod spec lint --verbose --use-libraries --allow-warnings --sources=xxxx.git,yyyy.git (私有库依赖需要添加specs源, 如果还依赖开源库需要添加官方源)
6.本地测试库是否可用
新建工程,切换到工程目录,执行命令
pod init
修改podfile文件, 并添加上本地库路径(含podspec文件的目录路径)
pod '库名', :path => '`~/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仓库(podspec文件中的s.version要在代码库的git上有对应的tag才能提交成功)
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)来打包,有两种安装方式:
1.直接通过gem命令安装
sudo gem install cocoapods-packager
2.找到 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://xxx.git,https://yyy.git :依赖库的远程specs,根据依赖库情况配置私有specs或者官方specs示例:
pod package WTNetworking.podspec --spec-sources=https://git.dev.xxxx.com/WTSpecs.git,https://github.com/CocoaPods/Specs.git --force --library
⚠️注意: 默认的符号添加前缀可能会造成问题:
- 参考另一个插件说明:cocoapods-mangle README.md,本人在测试的时候出现了问题,cocoapods-mangle插件直接处理AFNetworking就会报错,处理不到属性变量什么的(这个变量是id类型,并遵循某个协议),但是打包插件cocoapods-packager确没什么问题(测试过程发现packager会给类和常量添加前缀,不会给分类方法添加前缀)。
- C语言格式的函数: 本人测试“AFQueryStringFromParameters”是可以的并不会冲突。
- 打包SDK依赖的时候,建议头文件的引用写在.m文件中,比如:SDK 引用了AFNetworking ,但是把【#import "AFNetworking.h"】 写在了.h文件中并在打包的时候暴露了出来,但是在项目中有没有直接用到AFNetworking,那么就会提示找不到AFNetworking。
⚠️注意:应用工程配置
- 依赖的系统库需要 Build Phases -> Link Binary With Libraries添加库支持
- 如果SDK包含Category, Other Linker Flags 中添加 -ObjC
四、Cocopods其它插件
参考链接:Cocopods插件安装及说明
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。