CocoaPods
ShannonChenCHN opened this issue · 6 comments
常见问题
1. 如何引入只在 release 或者 debug 模式下参与编译的 pod?
pod 'FLEX', :configurations => ['Debug']
2. 输入 sudo gem install cocoapods 更新 CocoaPods时报错,
ERROR: While executing gem ... (Errno::EPERM)
Operation not permitted - /usr/bin/xcodeproj
解决:sudo gem install -n /usr/local/bin cocoapods
参考:https://segmentfault.com/q/1010000002926243
3. 更新 CocoaPods 的 repo 时输入命令: pod repo update
出现报错:
Updating spec repo master
$ /usr/bin/git pull --ff-only
error: RPC failed; curl 56 SSLRead() return error -9806
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
解决办法: cd ~/.cocoapods/repos/
git clone https://github.com/CocoaPods/Specs.git master
如果你已经有repos库了,也可以直接 git pull origin master 来更新本地库
4. CocoaPods 版本升级
5. Development Pods 目录是怎么来的?
http://www.cocoachina.com/ios/20150916/13471.html
6. 如何更新 podspec ?
pod trunk
相关命令负责和 CocoaPods API 打交道,所以,可以通过 pod trunk push
命令发布更新到 https://github.com/CocoaPods/Specs
仓库。而 pod spec push
可以更新私有库。
7. 执行 pod search
找不到第三方库时怎么办?
报错如下:
Unable to find a pod with name, author, summary, or descriptionmatching
解决办法:
执行下面的命令,删除 CocoaPods 的索引,然后重新 search。
rm ~/Library/Caches/CocoaPods/search_index.json
再次执行 pod search 命令时,会触发 CocoaPods 重新拉这个索引文件。
参考:https://www.jianshu.com/p/d2d81b58d716
7. pods 缓存管理
查看缓存: pod cache list
清除所有缓存: pod cache clean --all
8. 如何从项目中移除CocoaPods
- 删除本地文件(Podfile、Podfile.lock、Pods文件夹)
- 删除本地生成的xcworkspace文件
- 打开项目,在Frameworks文件夹下,删除Pods.xcconfig和libPods.a
- 进入项目Build Phases,删除Copy Pods Resources、Embed Pods Frameworks和Check Pods Manifest.lock 三项。
一、CocoaPods 的使用
1. CocoaPods 中,有几种设置 SDK 版本的方法。
如:
'>= 2.8.4' 会根据本地的 CocoaPods 源列表,导入不低于 2.8.4 版本的代码。
'> 2.8.4' 会根据本地的 CocoaPods 源列表,介于 2.8.42.9.0 之间版本的代码。
多人开发时最好锁定版本,便于团队开发。如,指定 2.8.4 版本。
2. 升级工程的 SDK 版本
更新工程目录中 Podfile 指定的 SDK 版本后,在终端中执行以下 pod update 命令。
3. 清除 CocoaPods 本地缓存
特殊情况下,由于网络或者别的原因,通过 CocoaPods 下载的文件可能会有问题。
这时候可以删除 CocoaPods 的缓存(~/Library/Caches/CocoaPods/Pods/Release 目录),再次导入即可。
4. 查看当前使用的 SDK 版本
可以在 Podfile.lock 文件中看到您工程中使用的 SDK 版本。
5. 关于 CocoaPods 的更多内容,可以参考 CocoaPods 官方文档
二、CocoPods 与 xcworkspace
http://nshipster.com/cocoapods/#using-cocoapods
https://yq.aliyun.com/articles/8315
https://objccn.io/issue-6-4/
https://zhuanlan.zhihu.com/p/22652365
https://github.com/CocoaPods/CocoaPods
http://www.jianshu.com/p/ad2e37e741bb
http://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/
http://www.jianshu.com/p/83b6e781eb51
iOS 如何在一个存在多个project的workspace中引入cocoapods管理第三方类库:https://yq.aliyun.com/articles/8315
iOS使用Workspace来管理多项目:http://www.jianshu.com/p/b6c59d8ed2c9
https://developer.apple.com/library/prerelease/content/navigation/#section=Topics&topic=Xcode
Xcode Workspace:https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html#//apple_ref/doc/uid/TP40009328-CH7-SW1
三、创建自己的 pods
总共要做三件事:
- 创建 GitHub 项目
- 为你的代码添加 podspec 描述文件
- 将 podspec 文件通过 trunk 推送给 CocoaPods 服务器
详细步骤:
- 在 GitHub 上为自己的项目 MyProject 创建 repo,并上传代码到 repo 中。
- 在项目根目录下执行下面的命令,创建 MyProject.podspec 文件,每个 Pods 依赖库必须有这个描述文件:
pod spec create MyProject
-
将 MyProject.podspec 文件内容修改成你想要的样子,记得写上正确的版本号。
具体格式可以参考官方文档 和 3分钟让你的框架支持cocoapods,podspec文件讲解。 -
将 MyProject.podspec 文件也提交到 GitHub 上。
-
pod 验证:
pod lib lint --allow-warnings
- 验证通过后,给项目打上 tag,提交到 GitHub。
- 在 pod 上注册 trunk
7.1 在 pod 上注册
pod trunk register shannonchenchn@foxmail.com 'shannonchen' --verbose
7.2 邮箱验证
7.3 注册成功以后,查看注册信息以及发布过的 Pods
pod trunk me
- 提交 MyProject.podspec 到 CocoaPods 官方仓库中
在 MyProject.podspec 文件所在的路径下执行:
pod trunk push MyProject.podspec --allow-warnings
- 在执行
pod trunk push
成功后,先用pod search
查找一下你的代码,如果搜索到了结果就代表可以直接使用了;没有搜到的话,就先执行pod setup
进行本地依赖库更新,然后再pod search
。
问题
1.创建 cocoaPods 库时遇到的坑:
- 如何更新 podspec
pod trunk
相关命令负责和 CocoaPods API 打交道,所以,可以通过 pod trunk push
命令发布更新到 https://github.com/CocoaPods/Specs
仓库。而 pod spec push
可以更新私有库。
延伸阅读
四、私有 pods 的创建
流程跟上面【三、创建自己的 pods】的流程差不多,只是需要先创建一个保存私有 pod spec 的仓库,然后将私有 pod spec 上传到这个私有仓库中,最后在使用时指明 source 为这个私有仓库的地址就可以了。
问题:
- 执行
pod spec lint
命令时出错:
Cocoapods: Unable to find a specification for [PrivateSpec] depended upon by [PrivateClientSpec]
原因:没有指明私有 pod spec 的 source。
解决办法:执行 pod spec lint
命令时,补充 source 参数。
参考:Cocoapods: Unable to find a specification for [PrivateSpec] depended upon by [PrivateClientSpec]
参考
CocoaPods 帮我们做了什么
主要组成
-
CocoaPods/CocoaPod: The CocoaPods command line tool.
-
CocoaPods/Core: Support for working with specifications and podfiles.
- Podfile: The file that defines the pods you want to use.(Podfile 实际上就是一个用 ruby 语法编写的文件)
- Podspec: A file that determines how a particular pod is added to a project.
-
CocoaPods/Xcodeproj: Create and modify Xcode projects from Ruby.
-
CocoaPods/cocoapods-downloader: Downloaders for various source types.
-
CocoaPods/CLAide: A small command-line interface framework.
-
CocoaPods/Molinillo: A powerful generic dependency resolver.
-
CocoaPods/Specs: Master repository of specifications.
执行 pod install
发生了什么
在你的工程目录下执行 pod install --verbose
,你可以看到 pod install
命令执行时的工作细节(以 didi/DoraemonKit
中的 DoraemonKitDemo 工程为例):
$ pod install --verbose
Preparing
Analyzing dependencies
Inspecting targets to integrate
Using `ARCHS` setting to build architectures of target `Pods-DoraemonKitDemo`: (``)
Finding Podfile changes
- AFNetworking
- DoraemonKit
Fetching external sources
-> Fetching podspec for `DoraemonKit` from `../../`
Resolving dependencies of `Podfile`
Comparing resolved specification to the sandbox manifest
- AFNetworking
- BSBacktraceLogger
- CocoaLumberjack
- DoraemonKit
- PNChart
- UICountingLabel
- UITextView+Placeholder
- fishhook
Downloading dependencies
-> Using AFNetworking (2.6.3)
-> Using BSBacktraceLogger (0.0.1)
-> Using CocoaLumberjack (3.4.2)
-> Using DoraemonKit (1.1.3)
-> Using PNChart (0.8.9)
-> Using UICountingLabel (1.2.0)
-> Using UITextView+Placeholder (1.2.1)
-> Using fishhook (0.2)
- Running pre install hooks
Generating Pods project
- Creating Pods project
- Adding source files to Pods project
- Adding frameworks to Pods project
- Adding libraries to Pods project
- Adding resources to Pods project
- Adding development pod helper files to Pods project
- Linking headers
- Installing targets
- Installing target `AFNetworking` iOS 7.0
- Generating dummy source at `Pods/Target Support
Files/AFNetworking/AFNetworking-dummy.m`
- Installing target `BSBacktraceLogger` iOS 8.0
- Generating dummy source at `Pods/Target Support
Files/BSBacktraceLogger/BSBacktraceLogger-dummy.m`
- Installing target `CocoaLumberjack` iOS 6.0
- Generating dummy source at `Pods/Target Support
Files/CocoaLumberjack/CocoaLumberjack-dummy.m`
- Installing target `DoraemonKit` iOS 8.0
- Generating Info.plist file at `Pods/Target Support
Files/DoraemonKit/ResourceBundle-DoraemonKit-DoraemonKit-Info.plist`
- Generating dummy source at `Pods/Target Support
Files/DoraemonKit/DoraemonKit-dummy.m`
- Installing target `PNChart` iOS 7.0
- Generating dummy source at `Pods/Target Support
Files/PNChart/PNChart-dummy.m`
- Installing target `UICountingLabel` iOS 5.0
- Generating dummy source at `Pods/Target Support
Files/UICountingLabel/UICountingLabel-dummy.m`
- Installing target `UITextView+Placeholder` iOS 6.0
- Generating dummy source at `Pods/Target Support
Files/UITextView+Placeholder/UITextView+Placeholder-dummy.m`
- Installing target `fishhook` iOS 6.0
- Generating dummy source at `Pods/Target Support
Files/fishhook/fishhook-dummy.m`
- Installing target `Pods-DoraemonKitDemo` iOS 8.0
- Generating dummy source at `Pods/Target Support
Files/Pods-DoraemonKitDemo/Pods-DoraemonKitDemo-dummy.m`
- Running post install hooks
- Podfile
- Writing Xcode project file to `Pods/Pods.xcodeproj`
- Generating deterministic UUIDs
- Writing Lockfile in `Podfile.lock`
- Writing Manifest in `Pods/Manifest.lock`
Integrating client project
Integrating target `Pods-DoraemonKitDemo` (`DoraemonKitDemo.xcodeproj` project)
- Running post install hooks
- cocoapods-stats from
`/Users/ShannonChen/.rvm/gems/ruby-2.2.7@global/gems/cocoapods-stats-1.0.0/lib/cocoapods_plugin.rb`
Sending stats
- AFNetworking, 2.6.3
- BSBacktraceLogger, 0.0.1
- CocoaLumberjack, 3.4.2
- DoraemonKit, 1.1.3
- PNChart, 0.8.9
- UICountingLabel, 1.2.0
- UITextView+Placeholder, 1.2.1
- fishhook, 0.2
-> Pod installation complete! There are 2 dependencies from the Podfile and 8 total pods installed.
- 读取本地的并解析 Podfile
- 分析 Podfile 中的依赖
- 下载依赖
- 创建
Pods.xcodeproj
工程- 生成 Pods.xcodeproj 工程
- 将依赖中的文件加入工程
- 将依赖中的 Library 加入工程
- 设置目标依赖(Target Dependencies)
- 创建 workspace
- 集成 xcproj 和 target
- 修改 build settings 相关属性
- 拷贝资源文件
- 保存修改到本地磁盘
- Podfile.lock
- Manifest.lock
- xcproj
pod install 和 pod update 的区别
每次在执行 pod install 或者 update 时最后都会生成或者修改 Podfile.lock 文件,其中前者并不会修改 Podfile.lock 中显示指定的版本,而后者会会无视该文件的内容,尝试将所有的 pod 更新到最新版。
Manifest.lock 的作用是什么
Manifest.lock 是我们在执行 pod install 时,在 Pods 目录中创建的缓存文件,其内容跟 Pod.lock 是相同的。
而 Pod.lock 是加入版本控制的,所以每次一旦有团队其他成员更新了 Pod.lock 后,当我们再执行 git pull 时,本地的 Pod.lock 就会随之更新。此时,如果我们如果直接 build 项目,Xcode 就会执行下面这段脚本(CocoaPods 在 Build Phases 中添加了 Check Pods Manifest.lock):
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
if [ $? != 0 ] ; then
# print error to STDERR
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
exit 1
fi
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
这段脚本所做的就是将 Manifest.lock 和 Pod.lock 进行对比,一旦发现有差异时,就会给出下面的错误提示:
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
一句话总结 CocoaPods 的原理
- 单独建一个 Pod Project 管理第三方库,每个第三方库对应一个 target,这个 Pod Project 对应的 target 依赖各个第三方库的 target
- 主工程通过
Link Binary With Libraries
隐式依赖 Pod Project 生成的libPods-xxx.a
文件,这样保证在编译主工程前先编译 Pod Project 中的文件 - 同时,通过
Pods-xxx.xcconfig
的文件来在编译时设置所有的依赖的路径和参数(比如LIBRARY_SEARCH_PATHS
),这样就能保证编译主工程和链接时能找到其中引用的第三方库中的符号
版本控制相关
- 将 Pods 目录加入版本控制:不需要特别的操作
- 不将 Pods 目录加入版本控制:此时需要将
.xcworkspace
和Podfile.lock
加入版本控制,并且在 CI 执行 build 前添加执行pod install
的任务