Mac终端的Cocoapods创建自己公有库
一,前言
-
为什么要用Cocopods
通常在开发的过程中,大多时候,我们会处理一类相同的操作,比如对于字符串String的邮箱验证,是否为空,手机号验证,或者一些UIView的动画操作,我们为了避免写一些重复的代码,可能经过类目或者延展的形式对原有的类进行了一个扩充。
还有一些是工程中一些基本的公共组件,比如城市列表,刷新控件,网络请求库或者商品的目录这种基本公共组件,在工程中好多地方需要调用,我们都可以进行封装成一个组件功能模块。为了以后方便在其他App中使用,我们可以使用Cocoapods把这些小点子,小功能,可以封装成一个pod,当下次使用的时候,只需简单配置就可以了。
这一点特别是在公司开发多个项目的时候,可以很方便快速的共享公共的代码,节约开发时间,这就是为什么好多公司喜欢组件化管理代码。至于库是创建私有的还是公共的,看自己和公司要求而定,大多情况下公司的是私有库pod。当然通过cocopods除了集成自己开发的功能模块外,还可以引用第三方发布到cocopods上的功能功能模块,比如友盟的分享,神策的统计等等好的功能模块。总之Cocopods 减少了代码的耦合性,提供了开发效率等等。
-
理解Cocopods原理
-
cocoapods的下载原理
举例: s.source = { :git => 'git@gitlab.xxx.net:ios-thirdpartservice/xxxreact.git', :tag => '1.0.0' } //s.source 位于.podspec内
当使用Cocoapods导入私有库时,Cocoapods先是根据:git => ‘git@gitlab.xxx.net:ios-thirdpartservice/xxxreact.git’找到对应的git仓库,然后根据:tag => ‘1.0.0’定位到对应tag的提交(如果没有注明Pod依赖库版本则定位到最后一次的提交),然后在这次提交中检索后缀为.podspec的文件(文件可以随便命名)。找到podspec文件后先要验证s.name是否与Podfile中的一致,如果不一致则install时会报错:[!]Unable to find a specification for ‘React’. 如果验证成功后,就会根据Podspec中的s.source_files找到需要导入的代码文件,并通过其他的的数据找到对应的配置文件或资源文件等。最后,将其下载到本地项目中。
当使用Cocopods导入共有库时,和以上原理也相同。只是共有库要将podspec文件上传到cocoapods。在导入的时候通过名字React去cocoapods匹配对应的podspec,然后根据s.source去找到对应的仓库和对应的版本,然后会再去匹配新的podspec,后边的步骤就完全相同了。
-
集成原理
当所有的依赖库都下载完后,Cocoapods会将所有的依赖库都放到另一个名为Pods的项目中,然后让主项目依赖Pods项目。这样,源码管理工作都从主目录移到了Pods项目中。Pods项目最终会编译成为一个名为libPods.a的文件,主项目只要依赖这个.a文件即可。对于资源文件,Cocoapods提供了一个名为Pods-resource.sh的bash脚本,该脚本在每次项目编译的时候都会执行,将Pods依赖库的各种资源文件复制到目标目录中。Cocoapods还通过一个名为Pods.xcconfig的文件来在编译时设置所有的依赖和参数。
-
libPods.a
-
Pods-resources.sh
-
Pods.xcconfig
-
-
版本控制原理
当执行完pod install之后,cocoapods会生成一个podfile.lock的文件。podfile.lock文件最大的用处在于多人开发。如果你没有在podfile中指定pods版本pod ‘React’,那么默认为获取当前React依赖库的最新版本。当团队中的某个人执行完pod install命令后,生产的podfile.lock文件就记录下了当时最新pods依赖库的版本,这时团队中的其他人check下来这份包含podfile.lock文件的工程以后,再去执行pod install命令时,获取下来的pods依赖库的版本和最开始用户获取到的版本一致。如果没有podfile.lock文件,后续所有用户执行pod install命令都会获取最新版本的React,这就可能造成一个团队使用的依赖库版本不一致,这对团队协作来说绝对是个灾难。在这种情况下,如果团队想使用当前最新版本的React依赖库,
有两种方案:
1、更改podfile,使其指向最新版本的React依赖库
2、执行pod update命令;鉴于podfile.lock文件对团队协作如此重要,所以应该加入到版本控制里面。 -
区分pod install 与 pod update
我们在使用这个工具时,最经常用到的命令就是pod install 和 pod update;这两个命令都能为我们安装指定的Pod库,但是他们的使用是有区别的,有各自不同的作用和适用场景;了解这两个命令的差异前,需要先对Podfile.lock文件有所了解;Podfile.lock文件中记录了每个pod的当前已安装版本,并锁定这些版本(.lock命名因此而来);当运行pod install命令时,它只解析尚未列在Podfile.lock中的依赖库,在下载并安装新的pod时, 会在Podfile.lock文件中写入新的pod库的当前指定版本;对于已经在Podfile.lock中列出的pod, pod install命令不会尝试检查是否有更新的版本;而是直接使用在Podfile.lock文件中的pod版本;
-
pod install
在项目中第一次使用CocoaPods时,安装指定的pod库需要使用这个命令;当在Podfile中 增加 或 删除 某个pod后, 使用这个命令进行更新;pod install不会尝试更新已安装的pod的版本;
-
pod update
1、当运行pod update时,CocoaPods会把Podfile中所有的pod都更新到最新版本;并在Podfile.lock中写入最新的版本号;
2、执行pod update PODNAME命令更新指定的某个PODNAME库到最新版本; -
pod outdated
pod outdated命令可以检测出所有比Podfile.lock中写入的版本(每个pod当前安装的版本)更新的pod版本;
-
-
-
了解Cocopods的本地目录
我们先来看看CocoaPods本地目录中有什么
-
$ cd ~/.cocoapods/repos/master 或者显示隐藏文件
-
$ defaults write com.apple.finder AppleShowAllFiles -boolean true ;
然后进入 ~/.cocoapods/repos/master
你会发现 master 是一个 git 仓库,输出仓库的远程地址,发现是一个GitHub仓库
-
$ git remote -v
origin https://github.com/CocoaPods/Specs.git (fetch) origin https://github.com/CocoaPods/Specs.git (push)
继续,我们进入Specs文件夹一直往里点,你会发现很多框架以及版本号
-
$ pod search YYImage
选择一个框架,通过pod搜索 Specs 文件夹中的框架,输出框架信息-> YYImage (1.0.4) Image framework for iOS to display/encode/decode animated WebP, APNG, GIF, and more. pod 'YYImage', '~> 1.0.4' - Homepage: https://github.com/ibireme/YYImage - Source: https://github.com/ibireme/YYImage.git - Versions: 1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0, 0.9.5, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.9 [master repo] - Subspecs: - YYImage/Core (1.0.4) - YYImage/WebP (1.0.4)
每个版本号对应的一个json文件,描述了每个对应版本的框架的信息、配置、及源码下载地。
我们在 CocoaPods 发布我们的框架时,就是要在 master 仓库中添加我们的仓库描述信息,然后push到远程仓库中。不过这个过程不用我们手动去操作,只需要通过pod命令进行操作即可。
-
二,iOS 创建自己的Cocoapods公有库及私有库
-
需要做的工作包括以下几点
-
创建一个本地的仓库,将自己的代码搞进去
-
将自己的代码上传到远程私有仓库中去
-
创建一个pods 的描述文件 .podspec
-
修改.podspec描述文件中的相关的描述信息
-
创建远程内部私有Spec Repo仓库
-
向私有的Spec Repo仓库中提交.podspec
-
在个人项目中的Podfile中增加刚刚制作的好的Pod并使用
-
后期的升级维护
-
-
具体详细的步骤如下
-
创建远程仓库注意点
-
-
-
正规的仓库都有一个license文件,Pods依赖库对这个文件要求比较严格,需要有这个文件,建议使用MIT类型的license
-
代码版本要打tag(要在代码版本上传以后打tag)
-
pod 支持 .a静态库、.framework 以及文件,不一定要是可运行的工程里面的某个组件
-
放代码的仓库不一定非要是Git仓库,只要是可以获取到相关代码文件就可以,可以是SVN的,也可以是zip包,区别就是在podspec中的source项填写的内容不同
-
-
- 创建一个pods 的描述文件 .podspec
-
如果你已经有先有工程可以使用如下命令直接创建.podspec文件
$ pod spec create MyViewExtension<这个名称一般和创建的项目名称一样就可以>
-
或者使用如下命令创建完整项目工程目录
$ pod lib create MyViewExtension <这个名称一般和创建的项目名称一样就可以>
使用这个命令会询问如下问题,根据项目情况选择即可
-
- 创建一个pods 的描述文件 .podspec
-
-
修改.podspec描述文件中的相关的描述信息
详情可参考CocoaPods的官网的PodSpec语法
Pod::Spec.new do |s| # 项目的名称 s.name = "MyViewExtension" # 项目的版本号,通过项目git的tag标签进行对应,这里的标签代表的版本 s.version = "0.0.1" # 项目简单的描述信息 s.summary = "Just Testing." # 项目的详细描述信息,注意,这里的文字的长度,一定要比上面的s.summary长,不然会认为格式不合格 s.description = <<-DESC this project provide all kind of KeychainDeviceID for iOS developer DESC # 项目的网页主页信息,这里可以直接写自己的远程仓库的主页的地址 s.homepage = "https://github.com/RunOfTheSnail/MyViewExtension" # 开源协议 s.license = "MIT" # 作者信息 s.author = { "zhangyan" => "17***24@163.com" } # 这个比较重要,指的就是git的对应的远程仓库的地址以及版本号,版本号直接获取的是上面的s.version # 项目地址,这里不支持ssh的地址,验证不通过,只支持HTTP和HTTPS,最好使用HTTPS # Supported Keys: # :git => :tag, :branch, :commit, :submodules # :svn => :folder, :tag, :revision # :hg => :revision # :http => :flatten, :type, :sha256, :sha1 s.source = { :git => "https://github.com/RunOfTheSnail/MyViewExtension.git", :tag => s.version } # 支持的平台及版本 s.platform = :ios, "11.0" # 支持的ios最低版本 s.ios.deployment_target = "7.0" # 如果是 Swift 的话指定 Swift 编译版本 # s.swift_version = "4.0" # 必备项,代码源文件地址,如果有多个目录下则用逗号分开,否则"public_header_files"等不可用 s.source_files = "GSLXYKeychainDeviceID/KeychainDeviceID/**/*.{h,m}" # 公开头文件地址 # s.public_header_files = "Pod/Classes/**/*.h" # 所需的系统framework,多个用逗号隔开,不需要后缀名 # s.framework = "SomeFramework" s.frameworks = "UIKit", "AnotherFramework" # 需要弱链接的框架 # s.weak_framework = "Twitter" # s.weak_frameworks = "Twitter", "SafariServices" #项目依赖的库文件(这个是系统的库文件),不需要后缀名,比如sqlite,libz等.以lib开头的需要省略掉lib这三个字母.例如:libz需要简写为z否则报错 # s.library = "iconv" # s.libraries = "iconv", "xml2" # 第三方或自己创建的 .Framework的名称 # s.vendored_frameworks = "YostarLib.framework" # 第三方或自己创建的 .a静态库的名称 # s.vendored_libraries = "libYostarStaticLib.a" # 添加资源文件 # s.resource = "XXX/XXXX/**/*.bundle" # s.resources = "XXX/XXXX/**/*.bundle" # CocoaPods会把这个库配置成static framework,同时支持Swift和Objective-C # s.static_framework = true # 依赖关系,该项目所依赖的其他,当在加载的时候也会一块把相关的依赖的库加载下来,如果有多个需要填写多个 # s.dependency "JSONKit", "~> 1.4" # 是否使用ARC,如果指定具体文件,则具体的文件使用ARC s.requires_arc = true # 指定项目配置,如HEADER_SEARCH_PATHS、OTHER_LDFLAGS等 # s.xcconfig = {"OTHER_LDFLAGS" => "-ObjC"} end
-
-
-
修改完毕之后进行检验一下.podspec的格式有木有问题
$ pod lib lint 完整lint格式 $ pod lib lint --allow-warnings --use-libraries --verbose --no-clean --sources='http://10.11.180.29/mobileDevelopers/YZT-Loan-Pod-Spec.git' --verbose:打印错误 --allow-warnings:允许警告,默认有警告的podspec会验证失败 --fail-fast:遇到错误马上停止,默认会完成全过程再停止 --use-libraries:如果自己私有库包含library,引用了.a、.framework,在验证和提交时需要加 --no-clean:检查问题 --sources:如果依赖了其他不包含在官方specs里的pod,则用它来指明源,比如依赖了某个私有库。多个值以逗号分隔
-
-
-
创建远程内部私有Spec Repo仓库
创建远程内部私有Spec Repo仓库, 需要到Github或其他代码托管平台创建远程仓库, 之后将远程仓库克隆到本地,终端执行如下命令:
// 这里可以用https或ssh地址方式克隆 $ pod repo add WBSpecs https://github.com/G***00/TestPodspec.git
注意:代码仓库和Spec Repo是需要分开存储的
克隆成功之后,我们可以查看一下:
$ open ~/.cocoapods/repos
本地cocoapods目录如下:
-
-
- 向私有的Spec Repo仓库中提交.podspec
-
首先将本地.podspec推送到远程私有repo spec仓库和本地repo spec仓库,终端执行如下命令:
$ pod repo push WBSpecs WBAvoidCrash.podspec
参数解析:repo spec仓库名称 .podspec名称
-
验证远程是否通过
推送成功之后,终端输入如下命令进行验证
$ pod spec lint WBAvoidCrash.podspec
-
验证私有仓库是否可用
用pod命令进行搜索,看能否搜索到:
$ pod search WBAvoidCrash
-
如果搜索不到,在终端执行如下命令
$ rm ~/Library/Caches/CocoaPods/search_index.json
或者更新本地仓库
$ pod repo update
然后重新search
-
- 向私有的Spec Repo仓库中提交.podspec
-
- 在个人项目中增加刚刚制作好的Podfile并使用
-
新建一个测试工程测试,用CocoaPods初始化项目,编辑Podfile文件:
#CocoaPods官方spec仓库 source 'https://github.com/CocoaPods/Specs.git' #自己私有spec仓库 source 'https://github.com/wenmobo/WBSpecs.git' platform :ios, '8.0' target 'TestDemo' do #防Crash库 pod 'WBAvoidCrash' end
-
编辑好podfile文件之后,终端执行:
$ pod install 安装时使用,更新库使用update命令 或 $ pod update 更新时使用
-
- 在个人项目中增加刚刚制作好的Podfile并使用
-
- 后期的升级维护
-
更新远程私有库中的代码
-
修改.podspec中的配置,version升级一个版本
-
给当前的远程仓库的代码,重新打个tag,tag和.podspec的version一样
-
远程仓库的代码更新完毕,接下来执行上面的 6.将当前本地的spec文件传到私有Spec Repo仓库的索引库中
-
检查测试一下,有没有上传到私有Spec Repo仓库的索引库中
-
- 后期的升级维护
- 删除私有的 Spec Repo
$ pod repo remove [name]
其实直接找到以后,手动删除就好了,然后在将Git的变动push到远端仓库即可
- 清理CocoaPods本地缓存
特殊情况下,由于网络或者别的原因,通过CocoaPods下载的文件可能会有问题
-
手动删除(~/Library/Caches/CocoaPods/Pods/Release目录)
-
打开终端,输入 pod cache clean AAA会删除AAA缓存库,使用$ pod cache clean --all清除所有缓存
-
三,iOS 创建自己的Cocoapods公有库
-
配置公有库PodSpec
配置方式和私有库一致
-
推送公有库到CocoaPods
-
通过pod来注册trunk,确认发送到邮箱的邮件,然后查看注册的个人信息。
# 注册trunk pod trunk register 邮箱 ‘用户名’ --description=‘描述’ # 查看个人信息 pod trunk me
- 验证上传的podspec是否有效,若未通过验证可根据提示进行修改。
# 验证公有库podspec是否有效 pod spec lint 公有库名称.podspec
- 将公有库推送到CocoaPods上。
# 推送公有库到CocoaPods pod trunk push 公有库名称.podspec
-
四,公有库和私有库有什么区别?
创建公有库和私有库,实际上原理是相同的, 不同的是, 两者的版本索引查询方式,公有库的podspec由CocoaPods/Specs管理,私有库需要自己建立一个仓库来管理podspec
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)