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 instal
l就可以了。更新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字样就代表已经成功卸载了。