根据pod的使用原理,当使用pod install
安装库时,会在索引仓库中搜对应的库,搜到后,根据索引仓中的spec文件中的信息,去对应的git仓库中拉取相应的代码。基于此,我们添加一个私有索引仓即可。官方文档:构建私有pod
本文记录创建私有仓的方法,以及提交一个测试项目到私有仓,再通过pod的方式加载测试项目的步骤。
一、构建远程私有库
我们需要准备两个空的远程仓库,一个作为私有索引库作为全部spec的存放仓库即索引库,另一个为模拟要发布的私有组件仓库。
第一步:创建私有组件库项目
这一步是通过pod 自带的cli命令创建项目,该项目中会将需要发布的代码以本地pod的方式引入,并同时创建测试项目以及对应的配置文件,为之后的发布做好准备。
将空仓库私有组件库clone到本地,cd进入目录后输入pod lib create XXXX创建新项目,XXXX 是项目名称,一般都会以组件名称命名。我们这里使用BaseMoudle作为组件名称,输入pod lib create BaseMoudle,然后填写相关信息后会自动生成项目(这里单词写错了,应该是Module,忽略这个小问题):
What platform do you want to use?? [ iOS / macOS ]
> iOS
What language do you want to use?? [ Swift / ObjC ]
> ObjC
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> no
What is your class prefix?
> Test
完成后项目会自动打开,项目结构如下:
目录结构如下:
最左边的BaseMoudle是git仓库clone的目录,中间的BaseMoudle是pod创建的项目所在的文件夹,右边的BaseMoudle才是真正放库代码的地方。
此时,发现git不能提交,并没有识别到这个新创建的项目,这是因为该文件夹下也有.git文件,这是pod的项目下载下来的,删掉即可(如果没有可以按键command + shift + . 显示隐藏文件)。
同时,为了方便期间,我们把中间这个多余的BaseMoudle层级也删除掉。
最终,目录结构如下:
第二步:修改.podspec文件
.podspec 文件是存放在索引库中的,pod会根据该文件中的配置去下载对应的文件。该文件最终会上传到索引库中。
打开工程后,找到BaseMoudle..podspec文件,该文件是默认生成的,必须修改的字段如下:
s.summary = '基础库'
s.description = <<-DESC
这里填写比summary更多的内容做为描述
DESC
s.homepage = '填写库的地址,比如https://gitee.com/xxxxx/xxxxx'
s.source = { :git => '填写库的代码地址,比如https://xxx.git', :tag => s.version.to_s }
这里,我们添加一些测试代码,需要将组件的代码放到这个文件夹下(ReplaceMe文件可以删除)。
正确的代码添加的方式是将代码放在和BaseMoudle.podspec
同层级的BaseMoudle ->Classes
文件夹下,然后在Example
文件夹下执行pod install
加载代码到项目中(即这是一个本地pod引入代码方式)。
提交代码后,需要给该次提交打一个标签,标签必须和.podspec文件中version
字段一致。默认这里是0.1.0
。
在BaseMoudle.podspec
同级目录中,可以使用指令pod spec lint 对文件进行验证(会检测填写的远程地址的是否可用,以及一些其他的合法性检测。)
注意:
- s.description 必须比 s.summary 更长,这里的格式也不能修改,写在DESC两个关键字中间一行
- s.source中,
:git =>
字段,这里如果写[email protected]这种地址,则需要使用pod ''xxx" 的用户是配置了SSH认证方式,否则会有权限错误。所以通常这里写https://xxx.git这样的方式确保可以正常拉取代码。- s.source中,
:tag =>
字段,理论上tag是一个字符串(git中关于tag官方文档描述),但仍需遵循一些规则。
具体规则详见文档。通常,我们以一个类似0.1.0
这样的方式设置tag。这是因为,在pod管理中,可以使用一些方式限定加载的版本,比如~>
之类的,只有这样的版本号才能正确解析。否则就需要指定版本号。
第三步:添加私有索引库搜索地址
在执行pod install
的时候,会在当前的pod索引库中查找库(使用pod repo
指令可以查看当前所有的索引库),为了能查询私有索引仓,我们需要添加私有仓地址到搜索库中。
使用pod repo add XxxName XxxPath
( 其中XxxName
是自定的repo名称,比如PrivateRepo
,XxxPath
为该索引库的地址,比如 https://xxx.git
)指令添加一个私有的全局pod 索引库。
添加完成后,可以使用pod repo
查看列表是否添加成功。
// 输入pod repo 后查看索引库信息
cocoapods
- Type: git (remotes/origin/master)
- URL: https://github.com/CocoaPods/Specs.git
- Path: /Users/x/.cocoapods/repos/cocoapods
Private
- Type: git (master)
- URL: https://xxx.git
- Path: /Users/x/.cocoapods/repos/Private
trunk
- Type: CDN
- URL: https://cdn.cocoapods.org/
- Path: /Users/x/.cocoapods/repos/trunk
第四步:将私有库的podspec文件推送到私有索引仓库中
在BaseMoudle.podspec
文件的所在的目录下执行pod repo push PrivateRepo BaseMoudle.podspec
,表示给PrivateRepo
索引库中推送podspec
(这里是pod的推送命令,并不是git的推送命令,该指令会检查.podspec文件的合法性):
Validating spec
-> BaseMoudle (0.1.0)
- WARN | source: Git SSH URLs will NOT work for people behind firewalls configured to only allow HTTP, therefore HTTPS is preferred.
- WARN | url: The URL (https://xxx.git) is not reachable.
- NOTE | xcodebuild: note: Using new build system
- NOTE | xcodebuild: note: Using codesigning identity override: -
- NOTE | xcodebuild: note: Build preparation complete
- NOTE | [iOS] xcodebuild: note: Planning
- NOTE | [iOS] xcodebuild: note: Building targets in dependency order
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `PrivateRepo' repo
Adding the spec to the `PrivateRepo' repo
- [Add] BaseMoudle (0.1.0)
Pushing the `PrivateRepo' repo
可以看到,这里会自动执行Pushing the
PrivateRepo' repo`指令,即对远程索引仓库自动进行git的push操作,将其更新到远程仓库。
注意,这里可以直接不写
BaseMoudle.podspec
参数,即pod repo push PrivateRepo
,会自动查找当前目录下的.podspec
文件。
第五步:安装远程库
默认pod 搜索的只是默认的索引库,我们需要在Podfile
文件中添加更多的索引库地址。
创建一个新项目,初始化pod后,在Podfile
文件最上方填写source信息(可通过pod repo指令查看),表示需要搜索的索引库地址,然后引入库文件pod 'BaseMoudle'
:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
source 'https://xxx.git'
target 'test' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for test
pod 'BaseMoudle'
end
执行pod install
即可
第六步:升级远程库(可选)
当需要对库进行升级时,需要修改.podspec
文件,同时,对代码重新打tag,和第二步一致。然后执行第四步,重新推送到本地repo。
在项目中,需要执行pod update --no-repo-update
,更新文件。这里使用pod install
是不行的,因为在Podfile.lock
文件中已经“锁定”了版本号,只有update指令才可以去更新这里的库,而--no-repo-update
表示更新repo中的文件(本地索引库),私有的索引库已经更新了(第六步中重新推送到本地repo),使用该命令可以避免更新官方的索引库(如果没有显式的指定其他库的版本号,不加--no-repo-update
会导致其他的库更新到最新版本从而引起一些问题)。
二、常见问题处理:
1.[iOS] file patterns: The `source_files` pattern did not match any file.
或者 [iOS] file patterns: The `resource_bundles` pattern for `xxx` did not match any file.
出现这中错误有几种可能:
字段设置错误
字段修改为第二步中的,特别是s.description
,要在<<-DESC
和DESC
写注释,不能删掉文件夹路径错误
在第一步中删掉多余的BaseMoudle层级才能正确匹配s.source_files = 'BaseMoudle/Classes/**/*'
字段,如果没有删除,则这里应该为s.source_files = 'BaseMoudle/BaseMoudle/Classes/**/*'
版本号没有修改
更新版本后没有修改版本号s.version
字段,即重复提交了相同的版本号。修改版本号后重新提交即可。
2.Could not find remote branch 0.1.0 to clone.
这个错误是由于没有打标签,会检测到找不到该标签。如果没有打标签这个错误不一定会有,gitee上不打也可验证通过,gitlab就会有这样的错误,可能和仓库有关系。但是在具体安装的时候(pod install),如果没有标签也会报错找不到该标签。
3.Specs satisfying the xxxx
dependency were found, but they required a higher minimum deployment target.
这个是安装的库的版本比podfile
中的版本高,在.podspec
文件中s.ios.deployment_target
字段配置版本信息。
4.Could not read from remote repository
报错信息如下:
[!] Error installing xxxxxxx
[!] /usr/bin/git clone [email protected]/xxxxx/xxxxxx.git /var/folders/f8/jkfbygnx2hvfx6s4k78vw51h0000gn/T/d20220406-63219-53c6s0 --template= --single-branch --depth 1 --branch 0.1.0
Cloning into '/var/folders/f8/jkfbygnx2hvfx6s4k78vw51h0000gn/T/d20220406-63219-53c6s0'...
ssh: Could not resolve hostname gitlab.autel.com: nodename nor servname provided, or not known
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
该问题并非git配置问题,是文件夹写入权限问题。执行一次sudo pod install
输入电脑密码,再执行一次pod install
即可正常安装。
5.库中有文件夹,引入后文件夹丢失
当只有一个文件夹或者文件夹中是空的时候,pod在引入的时候会对其进行过滤。这是一个正常现象
6. 只有WARN
和NOTE
仍然不能提交成功,提示[!] The `xxxxx.podspec` specification does not validate.
在后面添加--allow-warnings
参数即可。参考文章
7. 提交成功后别人使用pod install
仍然安装的是旧版本
这个问题是pod的索引缓存问题,通过pod repo update XXX
更新本地索引库即可。在本机上通过第四步已经推送到本地索引库上则无需此操作。
注意:这里自己虽然本地上的索引库已经更新,但是安装仍然是旧版,这是因为Podfile.lock
这个文件中会锁定版本信息。我们可以先注释引入的pod库,然后执行pod install
将其移除,再重新引入pod库,执行pod install
即可安装到最新版本了。
8. 报错- ERROR | [iOS] unknown: Encountered an unknown error (incompatible character encodings: UTF-8 and ASCII-8BIT) during validation.
检查s.source中配置的路径是否正确,这种错误往往是验证的url中存在异常字符