02 依赖管理:如何使用 CocoaPod 统一依赖库的管理?

在 iOS App 开发方面,几乎所有的 App 都需要使用到第三方依赖库。依赖库不仅能为我们提供丰富的功能,还能避免我们从头开发,在节省时间的同时也减少许多 Bug 。

但伴随着软件功能越来越丰富,依赖库数量越来越多,由此也出现了“依赖地狱”,比如依赖库循环依赖,底层依赖库版本冲突等。为了解决此类问题,于是,依赖库管理工具也就出现了。

目前流行的依赖库管理工具主要有:Git Submodules、Carthage、 Swift Package Manager 和 CocoaPods。在这里我们选择 CocoaPods。为什么呢?原因有三:

  1. CocoaPods 非常成熟,十分稳定,并且简单易用,学习成本低,效果明显;

  2. CocoaPods 会自动整合 Xcode 项目,使得其他项目成员在使用第三方库时无须任何额外的手工操作;

  3. CocoaPods 已经成为 iOS 业界标准,支持几乎所有的开源库和商业库,即便是 Objective-C 的依赖库以及二进制文件(binary)依赖库,CocoaPods 也提供支持。

那么,怎样使用 CocoaPods 来管理第三方依赖库呢?接下来我会从语义化版本管理、Pod 版本管理、Pod 版本更新三个方面展开介绍。

语义化版本管理

开发软件,免不了要更新迭代,所以每一次更新的版本号管理变得很重要。并且,一旦版本号混乱,就会导致一系列问题,比如很难查找和修改线上崩溃,没办法支持多团队并行开发,等等。为了避免此类问题,我们可以使用语义化版本管理(Semantic Versioning)来统一版本号的定义规范。

语义化版本号是一种通用的版本号格式规范,目前绝大部分优秀的第三方依赖库都遵循这一规范来发布版本。

具体来说,语义化版本号的版本号一般包括四部分:MAJOR、MINOR、PATCH、BUILD。每一部分都由递增的数值组成,例如 1.2.3.4,其中 1 是MAJOR, 2 是 MINOR。如果我们更新 MINOR 版本号,那么下一个版本就是 1.3.0.0。接下来我详细介绍下这四部分。

  • MAJOR 是指主版本号,通常在重大更新的时候才会需要更新主版本号。例如 iOS 每年都会更新一个主版本号。而对于第三方库来说,主版本号的更新,表示该库的 API 新增了重大功能,或者引入了不可兼容的更新 (breaking changes)。

  • MINOR 是指副版本号,用于小功能的改善。例如 iOS 14 在发布主版本后,在一年内可能发布多个副版本如 14.1、 14.2 来完善其系统功能。一般对于第三方库来说,副版本的更新就是新增一些 API,但不包含不可兼容的更新。

  • PATCH 是指补丁版本号,一般用于 bug fix 以及修复安全性问题等。对于第三方库来说,补丁版本号的更新也不应该有不可兼容的更新。虽然实际操作中这会有些困难,但我们可以通过把原有 API 标记为 deprecated,或者为新 API 参数提供默认值等办法来解决。

  • BUILD 是指构建版本号,通常在内部测试时使用。一般当我们使用 CI 服务器进行自动构建时,构建版本号会自动更新。

Pod 版本管理

要使用 CocoaPods 管理第三方依赖库,首先要新建一个 Podfile 文件,然后执行bundle exec pod install命令来安装所有依赖库。这时候 CocoaPods 会自动帮我们建立一个 Podfile.lock 文件和一个 Workspace文档。

注意,在第一讲我们说过,由于是通过 Bundler 来安装 CocoaPods,每次执行pod命令前,都需要加上bundle exec。不过为了简洁,后面涉及pod命令时,我会省略bundle exec部分。

接下来,我详细介绍下 Podfile 文件、 Podfile.lock 和 Workspace 文档到底是什么,以及如何使用。

Podfile 文件

Podfile 文件是一个配置文件,它主要是用来描述 Xcode 项目里各个 target 的依赖库。我们项目的 Podfile 文件可以在仓库中找到。在这里,我主要和你介绍一下 Podfile 文件中的几个重要配置。

source 配置

source用于指向 PodSpec(Pod 规范)文件的 Repo,从而使得 CocoaPods 能查询到相应的 PodSpec 文件。

具体来说,当使用公共依赖库的时候,source需要指向 CocoaPods Master Repo,这个主仓库集中存放所有公共依赖库的 PodSpec 文件。 由于 CocoaPods 经常被开发者吐槽 Pod 下载很慢,因此 CocoaPods 使用了 CDN (Content Delivery Network,内容分发网络)来缓存整个 CocoaPods Master Repo, 方便开发者快速下载。具体的配置方法就是使source指向 CND 的地址,代码示例如下:

source 'https://cdn.cocoapods.org/'

如果使用的是私有依赖库,我们也需要把source指向私有库的 PodSpec Repo,以使得 CocoaPods 能找到相应的 PodSpec 文件。 代码示例如下:

source 'https://my-git-server.com/internal-podspecs'

注意,当我们使用私有库时,执行pod install命令的机器必须能访问到source所指向的 Repo。

project 和 workspace

project用于指定我们的主项目文档。该项目文档会使用到 CocoaPods 管理的所有第三方依赖库。

workspace用于指定要生成和更新的 Workspace 文档。和其他依赖库管理工具不一样,CocoaPods 会自动生成一个 Workspace 文档,然后我们只能使用该文档而不是 Xcode 项目文档来进行后续开发。

代码示例如下:

project './Moments/Moments.xcodeproj'
workspace './Moments.xcworkspace'

这其中 Moments.xcodeproj 就是我们的主项目文档,它一般放在和项目名字相同的下一层目录下。

而 Moments.xcworkspace 是 CocoaPods 为我们生成的 Workspace文档,为了统一,我建议名字也是和主项目相同。

platform 和 use_frameworks

先看示例,它表示什么呢?

platform :ios, '14.0'
use_frameworks!

为了保证所有依赖库与主项目在编译和运行时兼容,我们指定的系统版本号需要和主项目所支持的系统版本号保持一致。而platform就是用于指定操作系统以及所支持系统的最低版本号。比如,例子中的platform :ios, '14.0'就表示支持 iOS 14.0 以上的所有 iOS 版本。

另外一行的use_frameworks!这一配置会让 CocoaPods 把所有第三方依赖库打包生成一个动态加载库,而不是静态库。因为动态库是我们经常用到的,它能有效地加快编译和链接的速度。

组织同类型的第三方依赖库

def dev_pods
  pod 'SwiftLint', '0.40.3', configurations: ['Debug']
  pod 'SwiftGen', '6.4.0', configurations: ['Debug']
end

其中configurations: ['Debug']用于指定该依赖库只是使用到Debug构建目标(target)里面,而不在其他(如Release)构建目标里面,这样做能有效减少 App Store 发布版本的体积。

def dev_pods end代码块是“复用同一类依赖库方式”的意思,我们可以把同类型的依赖库都放进这个代码块里面。比如,我们的 Moments 项目中就分别有dev_pods(开发相关的库),core_pods(核心库)以及thirdparty_pods(第三方库)等代码块定义。

target 配置

有了这些复用库定义以后,怎样使用到项目的构建目标(target)里面呢?下面就是一个例子。

target 'Moments' do
  dev_pods
  core_pods
  # other pods...
end

我们可以把构建目标所使用的所有依赖库放进target代码块中间,上面中的Moments就是我们的 App 构建目标。该构建目标依赖了dev_podscore_pods等各组依赖库。执行pod install的时候,CocoaPods 会把dev_pods代码块自动展开为SwiftLintSwiftGen,那么Moments构建目标能使用SwiftLintSwiftGen依赖库了。

依赖库的版本

 pod 'RxSwift', '= 5.1.1'
 pod 'RxRelay', '= 5.1.1'

在 CocoaPods 里面,每一个依赖库称为一个 Pod (注意这里首字母大写,Pod 指一个库),指定一个 Pod 的命令是pod(注意这里是小写,表示一条命令)。在 Podfile 里面我们可以通过这样的格式pod 'RxSwift', '= 5.1.1'来配置依赖库的版本号。其中,RxSwift或者RxRelay是依赖库的名字,5.1.1为版本号。这些库的名字以及版本号都可以在 CocoaPods 官网上找到。

为了统一管理第三方依赖库的版本,我建议统一使用 = 来锁定该依赖库的版本,这样就能保证每次执行pod install的时候都可以为同一个库下载同一个版本。

除了 = 操作符以外,CocoaPods 还支持其他操作符来指定版本:

  • > 0.1表示大于 0.1 的任何版本,这样可以包含 0.2 或者 1.0;

  • >= 0.1表示大于或等于 0.1 的任何版本;

  • < 0.1表示少于 0.1 的任何版本;

  • <= 0.1表示少于或等于 0.1 的任何版本;

  • ~> 0.1.2表示大于 0.1.2 而且最高支持 0.1.* 的版本,但不包含 0.2 版本。

这几个操作符相里面,~>(Squiggy arrow)操作符更为常用,它是以最后一个部分的版本号(例子中 0.1.2 的最后一个部分是补丁版本号 ..2)来计算可以支持的最高版本号。

例如~> 0.1.2表示 >= 0.1.2 并且 < 0.2.0,但不能等于 0.2.0, 因为 0.2.0 已经更新了副版本号而不仅仅是补丁版本号了。另外一个例子是~> 0.1,表示 >= 0.1 并且 < 1.0,举例来说,我们可以更新到 0.9 但不能更新到 1.0。

前面我介绍的是引用外部的第三方依赖库,如果我们的项目有自己的内部依赖库,要怎样在 CocoaPods 引用它呢?其实很简单,我们可以执行以下命令:

pod 'DesignKit', :path => './Frameworks/DesignKit', :inhibit_warnings => false

和其他外部依赖库不一样,我们需要使用:path来指定该内部库的路径。

Podfile.lock 文件

Podfile.lock 文件是由 CocoaPods 自动生成和更新的,该文件会详细列举所有依赖库具体的版本号。比如,

DEPENDENCIES:
  - Alamofire (= 5.2.0)
  - Firebase/Analytics (= 7.0.0)
PODFILE CHECKSUM: 400d19dbc4f5050f438797c5c6459ca0ef74a777

当执行pod install后,CocoaPods 会根据 Podfile 文件解释出各依赖库的特定版本号,然后一一列举在 DEPENDENCIES 下面。在上述的例子中,我们的 App 在构建过程中使用了5.2.0 的 Alamofire 库以及 7.0.0 的 Firebase Analytics 库。

PODFILE CHECKSUM 用于记录 Podfile 的验证码,任何库的版本号的更改,都会改变该验证码。这样能帮助我们在不同的机器上,快速检测依赖库的版本号是否一致。

我建议要把 Podfile 和 Podfile.lock 文件一同 commit 并 push 到 Git 代码管理服务器里面。特别是在团队开发的环境下,这样能帮助我们保证各个依赖库版本号的一致性。

在实践操作中,无论我们在哪台机器上执行pod install, PODFILE CHECKSUM 都不应该发生任何改变。因为我们在 Git 保存了 Podfile.lock,一旦我们发现老版本 App 的 Bug ,就可以根据该文件为各个依赖库重新安装同一版本号,来重现和定位问题,从而帮助我们快速修改这些 Bug。

Workspace 文档

Workspace 文档是 Xcode 管理子项目的方式。通过 Workspace,我们可以把相关联的多个 Xcode 子项目组合起来方便开发。

前面说过,当我们执行pod install的时候,CocoaPods 会自动创建或者更新一个叫作 Pods 的项目文档(Pods.xcodeproj )以及一个 Workspace 文档(在我们项目中叫作 Moments.xcworkspace)。

其中,Pods 项目文档负责统一管理各个依赖库,当我们在 Podfile 里面指定构建成动态库的时候,该项目会自动生成一个名叫Pods_<项目名称>.framework的动态库供我们项目使用。

而 Workspace 文档则统一管理了我们原有的主项目 (Moments.xcodeproj)以及那个 Pods 项目。

与此同时,CocoaPods 还会修改 Xcode 项目中的 Build Phases 以此来检测 Podfile.lock 和 Manifest.lock 文件的一致性,并把Pods_<项目名称>.framework动态库嵌入我们的主项目中去。

以上所有操作都是由 CocoaPods 自动帮我们完成。以后的开发,我们都可以打开 Workspace 文档而不是原有的 Xcode 项目文档来进行。

Pod 版本更新

使用 CocoaPods 管理第三方依赖库的操作非常简单,可是一旦使用不当,特别是在 Pod 更新的时候,很容易引起依赖库版本不一致,从而出现各种问题。

比如,在编译程序的时候,有些开发者可以顺利进行,而另外一些开发者编译时候就会出错;或者程序在本地编译时运行良好,一旦在 CI 上构建,就会出现 App 崩溃,等等。

那么,怎么保证更新 Pod 的时候都能保证版本一致呢?

下面结合我的实践经验,以第三方网络库 Alamofire 为例子和你介绍下。

第一步,CocoaPods 已经为我们提供了pod outdated命令,我们可以用它一次查看所有 Pod 的最新版本,而无须到 GitHub 上逐一寻找。下面是执行pod outdated命令的其中一条结果:

The following pod updates are available:
- Alamofire 5.2.0 -> 5.2.0 (latest version 5.4.0)

这表示当前我们使用了版本为 5.2.0 的 Alamofire ,其最新版本为 5.4.0。如果我们决定更新到版本 5.4.0,那么可以继续下一步。

第二步,在更新依赖库版本之前,为了避免在新版本中不小心引入 Bug,我们需要了解新的版本到底提供了哪些新功能,修改了哪些 Bug,与老版本是否兼容等事项。具体我们可以到 CocoaPods 官网上查找需要更新的第三方依赖库,然后在 GitHub 等平台上找到,并仔细阅读该库的版本说明(release note)。

请注意,我们要阅读当前使用版本到要更新的版本之间的所有版本说明。 在这个例子中,我们要阅读 5.2.1,5.2.2,5.3.0 和 5.4.0 的所有版本说明。这些版本说明会列出新增功能,更新的 API,修改的 Bug,有没有不可兼容的更新 。

第三步,在 Podfile 文件里把要更新的 Pod 的版本号进行修改。例如把pod 'Alamofire', '= 5.2.0'改成pod 'Alamofire', '= 5.4.0'。 然后执行pod install来重新生成 Podfile.lock 文件。

此时特别注意的是,我们要使用pod install而不是pod update。因为执行pod update会自动更新所有 Pod 的版本,这可能会更新了一些我们目前还不想更新的 Pod,从而会引入一些难以觉察的问题。

第四步,如果所更新的版本包含了不可兼容的更新,我们需要修改代码来保证代码能顺利完成编译。

第五步,很多第三方依赖库都是一些通用的基础组件,一旦发生问题会影响到整个 App 的功能,因此我们需要根据所更新的库进行回归测试。例如当更新了 Alamofire 库的时候,我们需要把每个网络请求都执行一遍,避免所更新的版本引入新的 Bug。

第六步,为了把更新的版本共享给所有开发者和 CI 服务器,我们需要把 Podfile 和 Podfile.lock 文件一同 commit 并 push 到 Git 代码管理服务器,并通过 Pull Request 流程并入主分支。

第七步,一旦更新的代码并入主分支后,要通过 Slack 等内部通信软件告诉所有开发者 pull 或者 rebase 主分支的代码,并执行pod install来更新他们开发环境的所有依赖库。

特别注意,千万不要使用pod update,因为pod update会自动把开发者机器上所有 Pod 的版本自动更新了。这种更新往往不是我们想要的结果,我们希望统一更新各个 Pod 的版本,并通过 Git 进行集中管理。

如果开发者在编译新代码前没有执行pod install命令,会出现以下的错误。

The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

这错误可以有效提醒所有开发者,需要再次执行pod install来更新他们本地的依赖库,从而保证所有开发者使用的依赖库的版本都是一致的。

另外,如果更新了基础组件的依赖库(如网络库),在测试阶段,我们还需要进行全面的回归测试。因为这些基础组件库的新版本如果有 Bug 很可能导致我们的 App 会发生大比例的崩溃,严重影响用户的体验。

有了上面的一流程,我们就可以有效地保证每个开发者使用的依赖库版本都是一致的,同时也能保证 CI 在自动构建 App 的时候所使用的依赖库版本也是统一的。

总结

这一讲我介绍了如何使用 CocoaPods 来统一管理依赖库的版本。特别是根据我自己的经验总结了一套更新 Pod 版本的流程,希望你灵活使用这些步骤,从而少走弯路。

[图片上传失败...(image-1d5139-1684744954659)]

这里我再特别强调一下,为了保证依赖库版本都能保持一致,尽量不要执行pod update,而是使用通过修改 Podfile 文件里的版本号并执行pod install来更新 Pod 的版本,然后把 Podfile 和 Podfile.lock 文件一同并入 Git 主分支中进行统一管理。

思考题:

CocoaPods 非常简单易用,它可以同时管理依赖库的依赖项,例如我们的 App 依赖 A 库, 而 A 库又依赖 B 库,同时 B 库依赖 C 库,CocoaPods 可以帮我们自动找出所有依赖项并按顺序安装所有依赖库。 那你知道 CocoaPods 是如何管理依赖库的依赖呢?

下一讲,我将为你介绍如何统一构建配置。

源码地址:

Podfile 文件地址:
https://github.com/lagoueduCol/iOS-linyongjian/blob/main/Podfile


[图片上传失败...(image-cb33d9-1684744954659)]

《大前端高薪训练营》

12 个月打磨,6 个月训练,优秀学员大厂内推,点击报名,高薪有你


精选评论

*虎:

如何回复讲师的回复?只能创建新的留言回复吗?

官方客服回复:

是的,想要回复讲师的答复,可以在新留言里面的开头标记说明就行

*虎:

"第七步,一旦更新的代码并入主分支后,要通过 Slack 等内部通信软件告诉所有开发者 pull 或者 rebase 主分支的代码,并执行pod install来更新他们开发环境的所有依赖库"能否把更新的依赖库也一并 push 到远端仓库,这样团队里其他开发人员就不需要额外 pod install 了?

讲师回复:

看得很仔细哦,更新和 push 到远程仓库的是 Podfile 以及 Podfile.log 文件,团队其他人员还是需要执行 pod install 安装并更新 Pods 文件夹,这个 Pod 文件夹存放的是所有第三方库的源码文件,我们一般并不把该文件夹放到 Git 里面。因此每个开发环境都需要执行 pod install 来更新。文章中提到,如果开发者不执行 pod install 是没有办法编译项目的,并且有错误提示。

**聪:

还不如直接看官网来的详细和简单!

讲师回复:

哈哈,技术的准确性都以官方文档为准哦。现在 iOS 开发已经不是学习了系统提供的 API 就可以了,还需要学习系统架构,自动化,代码规范,单元测试。在团队协助的时候还需要制定代码管理流程与规范。目前这些内容在苹果官网都没有提供官方的方案,我们的课程是通过一个类似朋友圈 App 作为案例把开发过程中的各个方面连贯起来讲述,希望能成为官方文档的一个补充。

**华:

老师讲的比较细

**不吃窝边草:

CocoaPods 管理依赖库的依赖,这种A依赖B,B依赖C,不是链表么?

讲师回复:

有时候并不是单链条的链表那么简单哦,可能是一个图,要为图找出依赖关系,需要使用拓扑排序。

**昆:

老师你好,关于pod update的描述,我有个疑问:如果是使用了 podName,'=version' 这时候 通过pod update 也会使用 = 号的版本号,而不会去所有都更新吧?

讲师回复:

不是的哦,一旦执行 pod update,会把版本号自动更新了。我们应该手动更新版本后,然后执行 pod install 来安装。

*一:

感谢老师的讲解😀

讲师回复:

也感谢你的支持。

*辰:

每个库的PodSpec文件里会配置它所依赖的库,CocoaPods 就是根据这个文件找出库的依赖库,依次类推。

*潇:

老师,如果pod里面的第三方库都指定了准确的版本号,是不是用 pod update 也可以?

讲师回复:

不是的,如果我们执行了 pod update 命令,就会把执行的机器中的第三方库版本给更新了,这不是我们想要的效果,为了保证整个团队都使用统一的版本,我们应该让一个人更新版本,并在测试完毕后合并到主分支供大家使用,一个团队在一个时间只有一个人更新第三方库的版本,其他人使用 pod install 来使用就可以了。

**超:

Cocopods 依赖库冲突怎么解决?

讲师回复:

请把问题描述清楚哦,这样我好方便回答。

**龙:

可能我自己写的不太清楚,思考题中,确实还不了解是通过什么算法来管理依赖库的依赖呢,这方面还请赐教。上网查了一些,不过总觉得不对。有关于第三库的管理和使用上,我举个例子,比如我使用Alamofire,一般会在项目中再封装一层,比如叫HttpUtils,而这个HttpUtils我通过Swift Package进行本地化的组件化管理,如果这个HttpUtils写的好,就放在公司内网,大家都可以使用。不知道这样表达是否清晰?

讲师回复:

我想问的是 CocoaPods 的内部实现,想让大家不仅会用,还知道里面是怎样实现的,一旦懂了原理,替换成不同的包管理工具都有一致的思路。你说到的情况(HttpUtils)其实是对的,我们在 Moments App 里面也有一个底层网络通信模块,在 APISession 里面。我们也可以把它独立出来成为一个 DesignKit 这样的组件。但是只要逻辑是结耦(目前已经是了),物理上的分离只是水到渠成的事情。同理,路由模块,数据存储那些都可以独立出来。

**泽:

老师,我自己新建了一个Moments工程, pod install以后,像这些Moments.xcodeproj/project.pbxprojMoments.xcodeproj/project.xcworkspace/contents.xcworkspacedataMoments.xcodeproj/xcuserdata/guoruize_account.xcuserdatad/xcschemes/xcschememanagement.plist这样的文件需要忽略吗, 还是让git管理起来。

讲师回复:

需要呀,请看看我们的 .gitignore 文件,在这里 https://github.com/lagoueduCol/iOS-linyongjian/blob/main/.gitignore#L122

**泽:

CocoaPods是通过.podspec文件 来管理依赖库,在这个文件里配置依赖库的依赖。不知道对不对。

讲师回复:

你说得对,第三方自己也使用 .podspec 文件来指明依赖库,可以一层层去找出所有依赖关系。

**龙:

在.podsepc文件中,有一个dependency参数来管理依赖库的依赖我现在的思路是用cocopods来管理第三方,考虑第三方一般都需要自己再封装一层,在现有项目中再创建SwiftPackage进行封装。

讲师回复:

哦哦,我不是很明白你说的办法,如果你想回答的是思考题的问题,我想问在 CocoaPods 里面到底是怎样计算出依赖项之间的依赖顺序,我的提示是它使用了一个算法,看看你能不能找出来哦。

**钦:

如果有一些自己搭建的私有pod ,合适在放在哪一步把私有的pod源引入呢?。

讲师回复:

我们会在 第 08 讲|设计组件:DesignKit 组件桥接设计与开发规范 讲述如何创建和使用私有 Pod。

**永:

每次思考的问题都没有配答案的吗

讲师回复:

后面会有编程题,那些题目比较容易验证,其他的思考题是想让大家多思考并把想法发出来,大家相互启发,共同学习与进步。

**泽:

老师您好,在团队项目中,像Podfile文件更改,只需要一个人去做吧,比如A把依赖1的版本改了, 执行了pod install命令, 在本地开发没问题,推到了git, B把依赖2的版本改了, 也推到了git,是不是团队成员每个人拉下来代码都需要先进行一次pod install,以保证最新的。

讲师回复:

是的呀,如果 Git 上的 Podfile 改动了,不执行 pod install 是不能编译项目的,所以你可以先编译,发现有问题再执行 pod install 来重新安装 Pod。

**6158:

谢谢老师的回复,我的意思是pod 'DesignKit', :path = false这里,在我看来是指向了一个本地路径?如果我的理解正确的话,那么是否所有设备都需要在相同的本地路径里保存一份相关代码?我目前只用过:git =,我的理解是:path =的区别只是一个在本地一个在git服务器上?

讲师回复:

是的,path 指本地路径,可以在代码库里面看到 DesignKit 在 Moments App 下的一个子目录,位于 Frameworks 里面。当我们 Git clone Moments 的 Repo 时就包含了 DesignKit 的源码了。如果有需要可以把 DesignKit 变成一个独立的 Repo,这个在 08 讲会详细讲述。

**彬:

我提问:Required ruby-2.7.1 is not installed.To install do: 'rvm install "ruby-2.7.1"'只要我在终端cd 到项目文件夹目录下,就会有这样的提示,我明明有装rbenv,有装ruby 2.7.1,那这个问题怎么解决?#讲师回复:请执行一下 rbenv versions 看一下到底有没有安装成功,这个安装过程需要一段时间哦。#回复讲师:我查看了一下 rbenv -v 是能查看到版本">1.1.2 的。但是我看到了,我电脑上是安装了 rvm 的,我现在卸载 rvm 看看,可能是 rvm 和 rbenv 的冲突

讲师回复:

是的呀,RVM 会和 rbenv 冲突的呀,我们在文章里面也提到过。如果可以,请只使用 rbenv。

**彬:

post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET' config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" end endend;;;Podfile中的这段代码没看懂是什么作用的。

讲师回复:

可以看一下这个 commit,这段代码用于解决一个构建时候的 warning https://github.com/lagoueduCol/iOS-linyongjian/commit/d30b4048aec9d1bc76626e410c83f208758c54f3#diff-8f7d6adf31268a2d897ee34bd170592648d6e520aa237104395e4a4438af50cb

*鹏:

您好,使用cocoapods依赖自己的库,是要将自己的库放到本地统一管理起来,然后使用:path链接到本地的路径吗?

讲师回复:

是的,我们会在第 08 讲讲述如何封装自己的 Pod。使用的时候就正如你说的那样 pod 'DesignKit', :path => './Frameworks/DesignKit', :inhibit_warnings => false

**6158:

请问内部依赖库是放在本地的吗?如果是的话,是需要所有设备都保存一份本地文件吗?

讲师回复:

请问你说是这些依赖库的源代码文件吗?我们只需要把 Podfile 和 Podfile.log 文件保存到 Git 服务器上,每次执行 bundle exec pod install 都能重新下载统一版本的依赖库到 Pods 文件夹里面。Pods 文件夹不需要放到 Git 服务器中。

*召:

团队成员的cocoapods的版本号也得保持一致

**彬:

Required ruby-2.7.1 is not installed.To install do: 'rvm install "ruby-2.7.1"'只要我在终端cd 到项目文件夹目录下,就会有这样的提示,我明明有装rbenv,有装ruby 2.7.1,那这个问题怎么解决

讲师回复:

请执行一下 rbenv versions 看一下到底有没有安装成功,这个安装过程需要一段时间哦。

**9149:

pod outdated这个好

**6126:

把source从https://cdn.cocoapods.org/改成https://github.com/CocoaPods/Specs.git后执行pod install提示 如下信息,根据提示修改还是无法解决Unable to add a source with url https://github.com/CocoaPods/Specs.git named cocoapods. You can try adding it manually in /Users/mengmengzhang/.cocoapods/repos or via pod repo add.

讲师回复:

哈哈,我也没有遇到个这个问题呀,但是临时 Google 了一下,找到答案啦,比如 Github 里面的回复 https://github.com/CocoaPods/CocoaPods/issues/9947#issuecomment-665182547 ,请试一下看看能不能帮到你。我也建议遇到问题先放狗 (Google),搞不好一下子就解决啦。

*东:

Pod 版本更新那个地方的几个步骤不错,有启发

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容