ios-第三方库引入之CocoaPods
ios-第三方库引入之CocoaPods
前篇
- CocoaPods使用 - https://juejin.cn/post/6844903731008536590
- 看一遍就会的CocoaPods的安装和使用教程 - https://www.jianshu.com/p/1711e131987d
CocoaPods是iOS开发、macOS开发中的包依赖管理工具,效果如Java中的Maven,nodejs的npm。
CocoaPods是一个开源的项目,源码是用ruby写的,源码地址在GitHub上。
无论是做iOS开发还是macOS开发,都不可避免的要使用到一些第三方库,优秀的第三方库能够提升我们的开发效率。如果不使用包依赖管理工具,我们需要手动管理第三方包,包括但不限于:
- 将这些第三方库的源码拷贝到项目中
- 第三方库代码有可能依赖一些系统framework,我们需要把第三方库依赖的framework导入到项目中
- 当第三方库有更新时,需要将更新过的代码拷贝到项目中
以上工作虽然简单,但是如果项目中的第三方库较多,需要耗费大量的时间和精力。CocoaPods可以将我们从这些繁琐的工作中解放出来。
安装 CocoaPods
安装 CocoaPods 比较方便。通常情况下,macOS都安装了 ruby,直接使用 ruby 的 gem 命令即可安装 CocoaPods。
查看有没有安装ruby, 如果能正确的输出版本号,则说明 ruby 已经正确安装
1
2$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]查看gem的版本号, 并替换源
1
2$ gem --version
3.0.3替换源. ruby的软件源 rubygems.org 使用的是亚马逊云的服务,国内普通网络是不能访问的。如果不能访问,可以将ruby的源换成国内淘宝的源
1
2
3
4
5
6$ gem sources --remove https://rubygems.org/ // 删除源
$ gem sources -a https://gems.ruby-china.com/ // 添加 淘宝源
$ gem source -l // 查看源
*** CURRENT SOURCES ***
https://gems.ruby-china.com/如果gem的版本号过低,安装CocoaPods可能会失败。所以在安装CocoaPods之前可以升级一下gem
1
2$ sudo gem update --system --verbose
Latest version already installed. Done.
安装 CocoaPods
1
2
3
4$ sudo gem install cocoapods --verbose
Fetching concurrent-ruby-1.1.8.gem
...
33 gems installed初始化 CocoaPods
1
2
3$ pod setup --verbose
// 等待过程可能有点长,成功后会看到
Setup completed查看 CocoaPods 有没有安装成功, 搜索
MJExtension第三方库看看1
2
3
4$ pod --version
1.10.1
$ pod search MJExtension
表示 pod 已经已经 ok 了.
若果报错:
[!] Unable to find a pod with name, author, summary, or description matching MJExtension, 先不用管, 直接进行下一步引入试试看能不能安装成功
CocoaPods 工作原理
CocoaPods的使用相对来说是比较简单的。那么CocoaPods是如何完成这些工作的?以及为何生成了一个Pods工程?
实际上,CocoaPods是将所有依赖的第三方库都放到了Pods项目中

所有的源码管理工作从住项目转移到了Pods项目中。
Pods项目最终会编译成一个libPods-项目名.a的文件,主项目只需要依赖这个.a文件即可。
引入 第三方库
在项目的指定模块引入 第三方库
在项目新建一个文件, 名为: Podfile, 内容如下 (规则参考: [Podfile 规则](#Podfile 规则))
1
2
3
4
5platform :ios, '9.0'
target 'UnityApi' do
pod 'YYModel'
end- target 就是要引入第三方库的 模块
- pod 就是第三方库
cd 到 Podfile 所在目录, 安装
1
$ pod install --verbose
如果报错提示需要更新库, 需要先更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54$ pod install --repo-update
然后会自动生成一个 pods 工程

同时主工程也也会引入对应的静态库

此时的静态并不存在, 所以下一步是构建静态库
3. 打开 pods 工程, 默认是没有 scheme, 创建需要的模块的 scheme (也就是 Pods-xxx, 库不用, 以为它会在模块编译时自动编译出来), 然后 cmd + b 编译出 静态库, 默认输出到项目中的 build 目录下
构建时一定要注意 cpu 架构一定要一致, 否则编译项目时报错链接不到静态库, 如: `Library not found for -lUICKeyChainStore`

有两种方式可以引用到第三方库
1. 将这几个编译出来的 静态库 移到 *UnityApi* 模块找的到的 `Products ` 的地方, 如 默认的是在 `DerivedData`:
`/Users/wilker/Library/Developer/Xcode/DerivedData/Build/Products/Debug-iphonesimulator`

(如果不移动这个编译出来的库, 会报错: `library not found for -lPods-UnityApi`)
2. (建议) 因为 pod 中的 scheme 默认是构建到项目的 `build` 目录下, 所以修改使用到第三方库的 target 的 `Products` 路径与 pod 的一致就行, 也就是修改 *build settigns -> build locations -> build products path* 为 `build` 目录

- 如果不生效, 将 *xcode -> preferences -> locations -> advanced* 中, 勾选 *shared folder*, 并改为 *build*, 然后重启编辑器构建

4. 在 *UnityApi* 模块下编写代码
```objective-c
// model
@interface User : NSObject
@property UInt64 uid;
@property NSString *name;
@end
@implementation User
@end
// 将 model 转成 字段
User* usr = [User new];
usr.name = @"hello";
usr.age = 123;
NSDictionary *dict = [usr yy_modelToJSONObject];
NSLog(@"--- dict: %@", dict);
结果:
1
2
3
42021-02-03 16:48:57.523644+0800 MyIosTest[34885:15899485] --- dict: {
age = 123;
name = hello;
}之后追加其他第三方库, 在 Podfile 增加其他第三方库, 重走引入流程即可.
三方库必须在 executable 模块中引入
比如: 写了个 api 库, api 库使用了 json 库, 而 executable 模块又是用了 api 库, 最终的引入方式是: executable 模块引入 api 库 和 json 库, 而 api 库不引入 json 库
如: Unity-iPhone 是 executable 模块, MJExtension 是 json 库

踩坑
编译报错: 链接不到第三方库
错误: library not found for -lPods-UnityApi
其实就是没有把 pods 工程编译出对应的 静态库移到正确的目录下
运行时闪退, 找不到第三方库
报错: unrecognized selector sent to instance
解决办法: 在 build settings -> other linker flags 中加多一个 -ObjC

-ObjC: 这个flag告诉链接器把库中定义的OC类和Category或nib都加载进来,编译后app会变大,以为加载了很多不必要的文件导致可执行文件变大。但是如果静态库中有类和分类只有加入这个flag才行;但是当静态库中只有分类而没有类时,-ObjC就失效了,这时需要加-all_load 或 -force_load了
参考: https://cloud.tencent.com/developer/article/1624205
Podfile 规则
多 模块 组合 第三方库
不同项目引入不同的第三方库 - https://stackoverflow.com/questions/14906534/how-do-i-specify-multiple-targets-in-my-podfile-for-my-xcode-project
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30platform :ios, '9.0'
inhibit_all_warnings!
use_frameworks!
def shared_pods01
pod 'YYModel', '~> 1.0.4'
pod 'UICKeyChainStore', '~> 2.2.1'
pod 'AFNetworking', '~> 4.0'
########### Facebook
pod 'FBSDKCoreKit', '~> 9.0.1'
pod 'FBSDKLoginKit', '~> 9.0.1'
pod 'FBSDKShareKit', '~> 9.0.1'
end
target 'MyIosTest' do
shared_pods01
end
target 'MyIosTestTests' do
shared_pods01
end
target 'UnityApi' do
shared_pods01
end
target 'UnityApiTests' do
shared_pods01
end
版本号指定
需要导入一个第三方库,只需要
1 | pod 'package name', 'version number' |
即可。版本号有多种表示方式,这里简单介绍几种:
‘1.0’ 只要该版本
‘>=1.0’ 最低版本号为1.0
‘<=1.0’ 最高版本号为1.0
‘
>1.0’ 兼容1.0的版本的最新版本, 也就是 1.02.0 之间
通常情况下使用 ~> 的方式。
参数说明
- Podfile文件用法详解 - https://www.jianshu.com/p/b8b889610b7e
参数
inhibit_all_warnings!
inhibit_all_warnings! 屏蔽所有来自于cocoapods依赖库的警告。你可以全局定义,也能在子target里面定义,也可以指定某一个库:
use_frameworks!
通过指定use_frameworks!要求生成的是framework而不是静态库。
如果使用use_frameworks!命令会在Pods工程下的Frameworks目录下生成依赖库的framework
如果不使用use_frameworks!命令会在Pods工程下的Products目录下生成.a的静态库
!!!!!!!!!!!!!!!!!!!! 修改这个参数后, 要把 pod 工程 clear 一下, 再编译, 否则可能出现 还是 编译出 .a, 而不是 framework !!!!!!!!!!!!!!!!!!!!
CocoaPods 相关的其他操作
增加新的第三方
如果使用过程中我还想添加其他的第三方怎么办,只要在Podfile里面接着添加,然后终端再执行
pod install就可以了。
更新CocoaPods中的第三方们。
第三方库们都有人在维护升级,我们需要隔断时间就要更新下我们工程中第三方库的版本。只需要终端输入命令
pod update就可以了。如果遇到
pod install或者pod update慢的问题,原因在于当执行以上两个命令的时候会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少。加参数的命令如下:
pod install --verbose --no-repo-update
pod update --verbose --no-repo-update删除CocoaPods中的某些第三方们。
当我们需要去掉某个第三方库时,只需要在Podfile删除该引入该库的语句,然后执行
pod update或者pod install就可以了。将CocoaPods从项目中删除
如果你在以后的使用过程中不想用CocoaPods了怎么办?很简单,把多出来的东西们都删掉就可以了,不过为了项目正常运行,你需要手动导入已经使用的第三方们哦。

升级CocoaPods
升级CocoaPods版本的命令和安装CocoaPods的命令一样,都是
sudo gem install cocoapods。
如果老版本升级cocoapods的时候提示Operation not permitted - /usr/bin/xcodeproj,改用命令sudo gem install -n /usr/local/bin cocoapods --pre就可以了。卸载CocoaPods
卸载CocoaPods的命令是
sudo gem uninstall cocoapods执行完命令后,最下面打印Successfully uninstalled cocoapods字样就代表已经成功卸载了。