Cocoapods的组件化私有库

引言

随着项目的越来越臃肿,那么需要对项目进行拆分进行模块化设置,而模块化则需要先把公共的部分都提取出来,构建成组件,做到一份组件各个模块共用,但是还需要做到可用可取消,这里就用到了Cocoapods的库导入机制,也是项目模块化的基础—组件化,所以需要做Cocoapods的组件化私有库。


目录

  • 1.私有spec center repository的创建
  • 2.私有库创建并将组件Spec 索引发布到私有center repository
  • 3.私有库的pod引入
  • 4.私有库的版本升级
  • 5.私有库的源码与二进制码的切换

私有spec center repository的创建

本地创建私有仓库的spec索引

我们创建spec repository是基于gitlab的,我们在github上创建一个空的仓库,命名为publicSpec,这个仓库是用来存放我们自己所有的私有库的spec文件,就如同官方的https://github.com/CocoaPods/Specs是用来存放所有官方的specs文件一样。
现在gitlab上创建一个名为publicSpec的仓库,然后终端执行:

1
pod repo add RGPublicSpec https://git.rograndec.com/publicModule/publicSpec.git

注意:上面的命令的解释如下:

1
pod repo add repo_name source_url

其中的 repo_name 是我们要添加的私有repo的名称(这里我们待会填的是: RGPublicSpec),后面是仓库的 gitlab 地址。这里做的其实是创建的工作,也就是在~/.cocoapods/repos目录下添加了一个以你的私有repo为名的文件夹,但是并没有添加spec文件。

然后你可以到~/.cocoapods/repo文件中去看是否有RGPublicSpec文件。如果有那么我们已经在本地得到我们自己的私有仓库 RGPublicSpec ,这是一个空的仓库,也是接下来需要用到的私有中央仓库。

clone仓库到本地

将仓库 clone 到本地,这里有多种操作方式,可以选择你喜欢的一种,这边选择使用命令行。首先需要切换到你想在本地存储的目录,然后再 clone ,在用户的根目录上:

1
2
cd ~
git clone https://git.rograndec.com/publicModule/publicSpec.git

完成后,我们进入到 ~/publicSpec 目录,这时候你看到是LICENSE和README.md文件,这里还有一个隐藏的 .git 文件,后续我们的所有文件都在这个目录下进行。

README.md

使用 github 的人应该都熟悉这个文件,它使一个成功的 github 仓库必不可少的一部分,使用 markdown 对仓库进行详细说明。

LICENSE

CocoaPods 强制要求所有的 Pods 依赖库都必须有 license 文件,否则验证不会通过。 license 文件有很多中,详情可以参考 tldrlegal。前面我们已经选择创建了一个 MIT 类型的 license。

注意:打开隐藏目录,可以使用命令:

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
55
56
57
58
59
60
//打开隐藏的命令:
defaults write com.apple.finder AppleShowAllFiles -bool true

//关闭隐藏的命令:
defaults write com.apple.finder AppleShowAllFiles -bool false
```

然后我们可以在gitlab也能看到对应的仓库

![](/images/iOS/center_repository.jpeg)

至此,整个spec center repository的创建就算全部完成了。

-------

### 私有库创建并将组件Spec 索引加入私有center repository


#### 1.首先创建一个文件夹SepcTest。


![](/images/iOS/component_dir.jpeg)


#### 2.终端进入当前文件夹SepcTest,执行下列命令:

![](/images/iOS/component_create.jpeg)

打开的项目结构如下:

![](/images/iOS/component_replace.jpeg)

这里注意,在第1步不能直接create group形式加入文件,这样加入的文件在文件夹根目录下,而文件源码需要加入`SpecTest——>SpectTestView——>SpectTestView——>Classes`路径下,最后是需要执行pod update将开发模式的源码引用到项目中,执行完后会发现加入的组件代码已经加进去了,如下图:

![](/images/iOS/component_originalcode.jpeg)

#### 3.编辑podspec文件信息

![](/images/iOS/component_podspec.jpeg)

> 接下来讲解一下每行代码的含义
s.name:名称,pod search 搜索的关键词,注意这里一定要和.podspec的名称一样,否则报错
s.version:版本号
s.ios.deployment_target:支持的pod最低版本
s.summary: 简介
s.homepage:项目主页地址
s.social_media_url:社交网址,如果你写的是你自己的博客的话,你的podspec发布成功后会@你
s.license:许可证
s.author:作者
s.source:项目的地址
s.requires_arc: 是否支持ARC
s.source_files:需要包含的源文件
s.public_header_files:公开的头文件
//其他
s.resources: 资源文件
s.dependency:依赖库,不能依赖未发布的库,可以写多个依赖库
常见的写法:
1、dependency:写法
```javascript
s.dependency = 'AFNetworking' , 'SDWebImage'

2、source_files: 写法(按照自身的目录结构来,默认是第一种)

1
2
3
'SpectTestView/Classes/**/*'
'SpectTestView/SpectTestView/*.{h,m}'
'SpectTestView/**/*.h'
1
2
3
'*'表示匹配所有文件
'*.{h,m}' 表示匹配所有以.h和.m结尾的文件
'**' 表示匹配所有子目录

3、source: 常见写法

1
2
3
s.source = { :git => "https://git.rograndec.com/publicModule/SpectTestView.git", :commit => "68defea" }
s.source = { :git => "https://git.rograndec.com/publicModule/SpectTestView.git", :commit => "68defea", :tag => 1.0.0 }
s.source = { :git => "https://git.rograndec.com/publicModule/SpectTestView.git", :tag => s.version }

commit => “68defea” 表示将这个Pod版本与Git仓库中某个commit绑定
tag => 1.0.0 表示将这个Pod版本与Git仓库中某个版本的comit绑定
tag => s.version 表示将这个Pod版本与Git仓库中相同版本的comit绑定。

4.上传到git

进入到当前项目根目录下(包含有.podspec文件),按照下列命令执行:

1
2
3
4
5
6
/// 本地验证(详细编译信息与忽略警告)
pod lib lint SpectTestView.podspec --verbose --allow-warnings
git add .
git commit -m "first commit"
git remote add origin https://git.rograndec.com/publicModule/SpectTestView.git
git push -u origin master

第一步是本地验证添加的podspec文件和本地组件源码格式,若无需编译信息和忽略警告,则后面可以不加--verbose --allow-warnings
后面几步就是git的提交步骤了
这里注意在最后一步会出现remote: Not Found fatal: repository 'https://git.rograndec.com/publicModule/SpectTestView.git/' not found,说明gitlab上没有对应的仓库,那么我们需要先到gitlab上去创建一个仓库(必须命名为SpectTestView对应),选择public权限(便于公共使用),创建后如图所示:

然后重新命令行执行git push -u origin master就会将组件项目上传到创建的仓库里,如图所示:

到这里我们已经完成私有组件库的创建上传。

5.将spec索引发布到私有center repository。

1.设置版本号,仍然在当前项目根目录下执行命令行:

1
2
git tag 0.1.0 -m "0.1.0版本"
git push --tags

2.验证文件, 本地与网络验证

1
2
3
4
/// 1. 本地验证(详细编译信息与忽略警告)
pod lib lint --verbose --allow-warnings
/// 2. 网络验证
pod spec lint

若上述命令都出现SpectTestView passed validation则表示验证通过则私有库版本创建成功完成,否则则需要重新修改配置或者代码,并且重点注意任何修改都必须进行版本升级,否则会出现同版本的指向不明给后面的引用带来问题。

3.将spec索引发布到私有center repository
命令行执行:

1
pod repo push RGPublicSpec SpectTestView.podspec

完成后可以到gitlab上私有center repository看看出现下列图示表示发布私有仓库成功。


私有库的pod引入

要将我们创建的私有库的源地址和Cocoapods本身的中央仓库源地址都加上,因为以前不写默认用Cocoapods本身的中央仓库源地址,但是加上我们自己的私有中央仓库有可能会覆盖掉默认的,导致引用的其他三方库出现找不到的情况。最后pod update一下,得到下面的图示:

这里我们能看到私有库SpectTestView pod导入进来了,而且pod模式下会自动将其依赖库AFN也引入了,极其方便。这就是前面讲的为什么需要做剔除依赖的二进制,因为依赖在pod引入私有库的时候会自动引入,保证了代码的纯粹性和依赖库的解耦。


私有库的版本升级

1.还原私有库的pod开发模式,主要是为了测试本地修改,如下图

然后通过命令行cd进入私有库项目根目录,然后cd Example进入存在podfile文件的目录下执行pod update这样就还原了开发模式。

2.更改升级需要进行的源代码,并且修改podspec文件描述及版本

3.退出到根目录,再执行上传git操作及将版本spec索引发布到私有center repository过程即可

1
2
3
4
5
6
7
8
/// 本地验证(详细编译信息与忽略警告)
pod lib lint SpectTestView.podspec --verbose --allow-warnings
git add .
git commit -m "修改版本"
git push
git tag 0.1.1 -m "0.1.1版本"
git push --tags
pod repo push RGPublicSpec SpectTestView.podspec

最后得到私有仓库spec索引更新

4.在使用该私有库的项目中pod update --verbose --no-repo-update即可更新到最新版本,如果发现到最新版本,那可能是Cocoapods版本较低,需要升级。


私有库的源码与二进制码的切换

1.切换目的
项目编译较慢,开发的时候为了加快效率当然需要以二进制码来进行,但是偶尔出现私有库版本需要做调试的情况或者说逻辑检测,这时候我们希望能看到源码,但是我们又不可能来来回回去替换文件,不仅操作不方便,而且极易造成文件缺失等问题,这里希望有一种方案能够通过pod直接来进行源码和二进制码的切换。

2.在当前私有库根目录下使用

1
pod packge SpectTestView.podspec --force

进行二进制打包,最后效果如下

最后需要的就是该framework文件

3.将打包生成的framework文件放入源码所在同一位置,这里我定义framework摆放位置SpectTestView/Products/SpectTestView.framework,注意这里的Products文件夹与SpectTestView/Classes/**/*中的classes位于同一层级,同时删除打包生成的根目录下文件夹SpectTestView-0.1.1,因为该文件已经没有作用了。

4.改写podSpec文件,定义的framework路径要与podSpec文件中设置的路径一致,同时加入IS_SOURCE和SpectTestView两个参数来判断切换。
当然源码和framwork代表的文件意义不一样,如图所示:

说明:
1.因为存在修改,所以一定要升级。
2.ENV表示环境参数判断,后面会告知如何使用,这里意思是IS_SOURCE或者SpectTestView参数不为空的情况下,加载s.source_files的源码,否则加载s.vendored_frameworks的二进制码内容。为什么这里需要有两个参数判断,原因是前者是所有私有库统一切换的判断参数,后者是单独对应的私有库切换的判断参数。

5.升级版本操作,上传gitlab和发布spec(过程请看私有库的版本升级篇)

6.源码和二进制码的pod处理

首先在podfile文件中正常引入配置

然后在podfile对应的根目录下执行

1
IS_SOURCE=1 pod update

这一句在执行pod更新时将IS_SOURCE加入环境变量参数,按照第4步的说明应该是引入源码了,我们看看最终结果:

可以看到与我们设计的基本是一致的,那么同理执行

1
SpectTestView=1 pod update

引入的也是源码

最后我们直接执行,不带上任何环境变量,按照设计应该载入的是打包的二进制码

1
pod update

得到的结果视图为:

出现这种原因是因为cocoapods的缓存,所以我们这里需要暴力处理,清除cocoapods的缓存,重新pod update执行

1
2
sudo rm -fr ~/.cocoapods/repos/RGPublicSpec/SpectTestView
pod cache clean SpectTestView

最后的切换结果如图所示:

至此,关于私有库源码与二进制的切换则说明完成。