iOS 私有库创建与推送远程------问题排查总结文档
场景:使用 CocoaPods 创建 iOS 私有库并推送到 Gitee 远程仓库,过程中遇到的一系列报错与解决记录。 适用对象:iOS 开发者 / CocoaPods 私有组件维护者。
一、核心概念(必须分清两个仓库)
| 仓库 | 作用 | 内容 | 使用命令 |
|---|---|---|---|
源码仓库 my-private-sdk |
存放组件代码 | Classes/ 源码、.podspec、git tag |
git remote add / git push / git tag |
Spec 索引仓库 my-private-specs |
存放 podspec 描述索引 | 各版本 0.1.0/xxx.podspec(不放源码) |
pod repo add / pod repo push |
⚠️ 两个仓库必须分开、独立,绝对不能混用地址,这是整套方案最容易出错的地方。
关键理解:一个 Spec 仓库可管理多个私有组件
- 源码仓库:每新增一个私有库,就要新建一个独立的源码仓库(组件代码互相独立)
- Spec 索引仓库 :全局只维护 1 个,所有内部组件的 podspec 都集中放这里,一次创建、长期复用
- 所以新增第二个、第三个私有库时,不需要新建 Spec 仓库 ,复用已有的
MyPrivateSpecs即可
二、完整正确步骤(标准私有库方案·创建第一个库)
0. 前置
- 本地安装 CocoaPods:
gem install cocoapods,验证pod --version - Gitee 网页新建两个空仓库 :
my-private-sdk(源码仓库)my-private-specs(Spec 索引仓库)
- ⚠️ 创建时不要勾选 README、.gitignore、license,必须是纯空仓库
1. 创建本地私有库模板
bash
pod lib create MyPrivateSDK
# 交互选择:iOS / ObjC或Swift / 带Demo / 测试框架None
cd MyPrivateSDK
- 代码放入
MyPrivateSDK/Classes/(不是 Example)
2. 修改 podspec
- 重点:
s.version、s.source(指向源码仓库 git 地址 + tag) s.version必须与后面 git tag 完全一致
3. 推送源码仓库并打 tag
bash
git add .
git commit -m "init v0.1.0"
git remote add origin https://gitee.com/<user>/my-private-sdk.git
git push -u origin main
git tag 0.1.0
git push origin 0.1.0
4. 添加 Spec 仓库
bash
pod repo add MyPrivateSpecs https://gitee.com/<user>/my-private-specs.git
pod repo list
5. 校验 podspec
bash
pod lib lint MyPrivateSDK.podspec --allow-warnings
# 必须看到 passed validation
6. 推送 podspec 到 Spec 远端
bash
pod repo push MyPrivateSpecs MyPrivateSDK.podspec --allow-warnings
7. 使用方 Podfile
ruby
source 'https://gitee.com/<user>/my-private-specs.git'
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'TestApp' do
pod 'MyPrivateSDK', '~> 0.1.0'
end
bash
pod install
8. 迭代发版流程
改代码 → 改 s.version='0.2.0' → commit → git tag 0.2.0 && git push origin 0.2.0 → pod lib lint → pod repo push
三、新增第二个私有库完整步骤(复用同一个 Spec 仓库)
前提:
MyPrivateSpecs已配置好(远端仓库有 main 分支、本地pod repo add已成功) ✅ 核心:不需要新建第二个 Spec 仓库 ,也不要再次执行pod repo add,只新建新组件的源码仓库
1. Gitee 网页新建【第二个组件源码仓库】
仓库名例如:MyImageLoaderSDK
- 类型:私有
- ❌ 不要勾选 README、gitignore、license,创建纯空仓库
2. 本地创建 pod 库模板
bash
pod lib create MyImageLoaderSDK
cd MyImageLoaderSDK
- 交互选项与之前一致(iOS、语言、带 Demo、测试框架 None)
- 源码放入
MyImageLoaderSDK/Classes
3. 修改 MyImageLoaderSDK.podspec
ruby
Pod::Spec.new do |s|
s.name = 'MyImageLoaderSDK'
s.version = '0.1.0'
s.summary = '图片加载私有组件'
s.description = <<-DESC
图片加载内部私有SDK
DESC
s.homepage = 'https://gitee.com/<user>/my-image-loader-sdk'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'xxx' => 'xxx@xx.com' }
s.source = { :git => 'https://gitee.com/<user>/my-image-loader-sdk.git', :tag => s.version.to_s }
s.ios.deployment_target = '12.0'
s.source_files = 'MyImageLoaderSDK/Classes/**/*'
end
s.name必须与库名一致,s.version初始0.1.0
4. 源码推送到【新组件源码远端】并打 tag
bash
git add .
git commit -m "init MyImageLoaderSDK v0.1.0"
git remote add origin https://gitee.com/<user>/my-image-loader-sdk.git
git push -u origin main
git tag 0.1.0
git push origin 0.1.0
5. 校验 podspec(必须)
bash
pod lib lint MyImageLoaderSDK.podspec --allow-warnings
# 看到 passed validation 再往下
6. push podspec 到同一个私有 Spec 仓库 MyPrivateSpecs
✅ 重点:仍用之前的
MyPrivateSpecs,不要新建 spec 仓库
bash
pod repo push MyPrivateSpecs MyImageLoaderSDK.podspec --allow-warnings
成功后远端 my-private-specs 自动新增目录:
markdown
MyImageLoaderSDK/
└── 0.1.0/
└── MyImageLoaderSDK.podspec
现在该 Spec 仓库同时管理:MyPrivateSDK、MyImageLoaderSDK。
7. 项目 Podfile 同时引入多个私有库
ruby
# 共用同一个私有 spec 源
source 'https://gitee.com/<user>/my-private-specs.git'
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'DemoApp' do
pod 'MyPrivateSDK', '~>0.1.0'
pod 'MyImageLoaderSDK', '~>0.1.0'
end
bash
pod install
8. 其他同事电脑使用
只需执行一次即可拉取所有私有组件:
bash
pod repo add MyPrivateSpecs https://gitee.com/<user>/my-private-specs.git
四、对话中遇到的具体问题与解决
问题 1:git remote add origin 之后 push 失败(远端仓库没建)
现象 :push 报 Repository not found 原因 :git remote add origin xxx.git 只是本地记录地址 ,远端仓库必须先建好。 解决:
- Gitee 网页先新建空仓库(不勾选任何初始化选项)
- 复制仓库 HTTPS/SSH 地址
- 再执行
git remote add origin <地址>+git push
勾选了 README 会导致
refusing to merge unrelated histories冲突,所以建仓必须纯空。
问题 2:没执行 pod repo add 也能 pod install 成功
原因 :使用了另一种简易写法,完全绕过了 Spec 索引仓库:
ruby
# 简易写法:直接指向源码仓库 + tag,不需要 pod repo add
pod 'MyPrivateSDK', :git => 'https://gitee.com/<user>/my-private-sdk.git', :tag => '0.1.0'
对比:
| 写法 | 机制 | 是否需 spec 仓库 |
|---|---|---|
:git => ... , :tag => ... |
直接拉源码仓库对应 tag,绕过索引 | ❌ 不需要 |
'MyPrivateSDK', '~>0.1.0' |
走 Spec 索引查找 → 按 spec 里的 source 拉源码 | ✅ 必须 pod repo add |
pod repo add不执行也能拉取 = 你用的是:git/:tag简易方案。多组件、需版本约束~>、pod search、团队协作时才需升级到标准 Spec 方案。
问题 3:git repo MyPrivateSpecs xxx.git 报 unknown subcommand
原因 :把 CocoaPods 命令误当成了 git 命令。 解决 :命令是 pod repo ,不是 git repo。git 本身没有 repo 子命令。
问题 4:pod repo MyPrivateSpecs xxx.git 报 Unknown command
原因 :pod repo 后面缺少子命令 add 。 解决:
bash
pod repo add MyPrivateSpecs <spec仓库git地址>
# 语法:pod repo add <本地别名> <远端spec仓库url>
问题 5:An unexpected version directory 'Classes' was encountered 报错
现象 :push 后本地 Spec 仓库目录出现 Classes 文件夹。 原因 :Spec 仓库目录结构被破坏。正确结构只允许版本号目录:
bash
MyPrivateSpecs/
└── MyPrivateSDK/
└── 0.1.0/
└── MyPrivateSDK.podspec # ✅ 正确
解决:
pod repo remove MyPrivateSpecs删掉本地坏仓库- 清空 Gitee 远端 my-private-specs 残留文件
- 重新
pod repo add(地址必须用 my-private-specs.git) cd MyPrivateSDK→pod lib lint→pod repo push
记住:Spec 仓库只存 podspec,绝不放 Classes 源码,源码在 my-private-sdk 仓库。
问题 6:Your configuration specifies to merge with the ref 'refs/heads/master' ... but no such ref was fetched
现象 :pod repo add 后 pull 报找不到 master 分支。 原因 :Gitee 远端 my-private-specs 是空仓库,没有任何分支 (main/master 都不存在)。 解决(先给 Spec 远端初始化一个主分支):
bash
# 1 删本地
pod repo remove MyPrivateSpecs
# 2 临时目录初始化并推送 main 分支到远端
mkdir tmpSpecRepo && cd tmpSpecRepo
git init
touch README.md
git add README.md && git commit -m "init spec repo main branch"
git remote add origin https://gitee.com/<user>/my-private-specs.git
git push -u origin main
# 3 Gitee 网页将默认分支设为 main
# 4 重新添加
pod repo add MyPrivateSpecs https://gitee.com/<user>/my-private-specs.git
# 5 回 SDK 目录
cd ../MyPrivateSDK
pod lib lint MyPrivateSDK.podspec --allow-warnings
pod repo push MyPrivateSpecs MyPrivateSDK.podspec --allow-warnings
main / master 都支持,关键是远端仓库至少有一个分支。临时目录用完可删。
五、命令速查表
| 操作 | 命令 |
|---|---|
| 新建库模板 | pod lib create <SDK名> |
| 校验 podspec | pod lib lint <SDK>.podspec --allow-warnings |
| 查看本地 spec 仓库 | pod repo list |
| 添加 spec 仓库 | pod repo add <别名> <spec仓库url> |
| 推送 podspec | pod repo push <别名> <podspec> --allow-warnings |
| 删除本地 spec 仓库 | pod repo remove <别名> |
| 查看远端分支 | git ls-remote https://gitee.com/<user>/my-private-specs.git |
六、高频坑点总结
- 两仓库地址混用 → Spec 仓库地址填成源码仓库,导致目录错乱/Classes 报错。
- 建仓勾选 README → 本地 push 时
unrelated histories冲突;Spec 仓库空无分支 → master 找不到。 - 命令写错 → 是
pod repo add,不是git repo,不是pod repo MyPrivateSpecs。 - 版本不一致 →
s.version与 git tag 必须严格一致,否则拉取失败。 - 路径大小写 → macOS 大小写敏感,
s.source_files路径写错会 lint 失败。 - 内网私有仓库 → 建议用 SSH 地址
git@gitee.com:<user>/xxx.git,提前配置 SSH 免密。 - pod repo push 失败排查顺序 → spec 语法 → 远端 spec 仓库权限 → tag 是否存在 → 分支是否存在。
新增私有库专项坑点
| 操作 | 是否需要新建远端 Git 仓库 |
|---|---|
| 新增一个私有组件(新 SDK) | ✅ 新建源码仓库 |
| 新增一个私有组件 | ❌ 不用新建 Spec 仓库,复用 MyPrivateSpecs |
| 组件升级版本 | ❌ 不用新建任何仓库,只需打新 tag + push spec |
新增组件时执行 pod repo add |
❌ 不需要,本地已存在 MyPrivateSpecs |
⚠️ 多个组件不能共用一个源码仓库,每个组件源码仓库必须独立。
七、快速判断用哪种方案
- 临时 / 个人 / 单组件 →
:git => ... , :tag => ...(无需维护 Spec 仓库) - 多组件 / 版本约束 / 团队协作 / pod search → 标准 Spec 仓库方案(需
pod repo add+pod repo push)
八、pod lib lint 常见警告与修复
关键认知:警告 ≠ 编译错误 。
pod lib lint默认规则是「存在警告即判定校验失败」,加--allow-warnings可放行警告完成校验。正式组件建议修复核心警告,避免长期依赖--allow-warnings。
警告 1:summary: The summary is not meaningful.
- 原因 :
s.summary描述过于简单(如只写"工具库")。 - 修复:填写一句简短清晰的组件功能介绍。
ruby
s.summary = "iOS 项目通用工具集合,提供字符串、日期、UI相关工具方法"
警告 2:description: The description is shorter than the summary.
- 原因 :
s.description详细描述文本比摘要还短,不符合规范。 - 修复:description 内容长度必须大于 summary。
ruby
s.description = <<-DESC
iOS 项目通用工具集合,封装常用字符串处理、日期转换、设备信息、UI辅助等工具方法,内部项目使用。
DESC
警告 3:problem validating the URL(homepage 不可访问)
- 原因 :CocoaPods 校验器无法访问
s.homepage地址;私有仓库最容易出现(外网访问不了私有主页/地址写错/仓库不存在)。 - 处理 :
- 公开库:核对并保证地址可访问
- 私有内部库:该警告基本无法消除,可忽略,用
--allow-warnings放行
警告 4:iOS swift: The validator used Swift 4.0 by default because no Swift version was specified.
- 原因:podspec 未声明 Swift 版本,lint 默认按 Swift 4.0 校验。
- 修复 :在 podspec 添加
s.swift_versions(OC 库也可加上,不影响 OC 代码)。
ruby
s.swift_versions = ['5.0']
修复后的 podspec 片段(综合示例)
ruby
Pod::Spec.new do |s|
s.name = 'MyProjectTool'
s.version = '1.1.0'
s.summary = 'iOS 项目通用工具集合,提供字符串、日期、UI相关工具方法'
s.description = <<-DESC
iOS 项目通用工具集合,封装常用字符串处理、日期转换、设备信息、UI辅助等工具方法,内部项目使用。
DESC
s.homepage = 'https://github.com/yourname/MyProjectTool'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'yourname' => 'xxx@xx.com' }
s.source = { :git => 'https://github.com/yourname/MyProjectTool.git', :tag => s.version.to_s }
s.ios.deployment_target = '12.0'
s.source_files = 'MyProjectTool/Classes/**/*'
s.swift_versions = ['5.0'] # 新增,修复 Swift 版本警告
end
校验命令
bash
# 修复 podspec 后优先尝试不带 --allow-warnings
pod lib lint MyProjectTool.podspec
# homepage 链接警告依然存在(私有仓库场景)时使用
pod lib lint MyProjectTool.podspec --allow-warnings
# 看到 passed validation 即为通过
九、pod repo push 命令报错排查
报错:[!] A spec-repo name or url is required.
- 原因 :
pod repo push命令语法不全,缺少「spec 仓库别名」和「podspec 文件」两个必填参数。 - 正确语法:
bash
pod repo push 【spec仓库别名】【podspec文件】 --allow-warnings
- 示例:
bash
# 错误(不带参数,会报 required 错误)
pod repo push
# 正确
pod repo push MyPrivateSpecs MyProjectTool.podspec --allow-warnings
- 查看本地 spec 仓库别名:
bash
pod repo list
# 第一列就是别名,填入 push 命令
关键前置:版本号必须与源码 tag 严格一致
push 的 s.version(如 1.1.0)对应的源码仓库必须打好同名 tag 并推送到远端 ,否则 pod install 拉不到代码:
bash
git tag 1.1.0
git push origin 1.1.0
appintentsmetadataprocessor相关日志只是 Xcode 编译 note,完全不用处理。