OC组件化06:【方案二】cocoapods组件化

张建 lol

背景

  • 随着公司业务的不断发展,应用的代码体积将会越来越大,业务代码耦合也越来越多,代码量也是急剧增加

  • 如果仅仅完成代码拆分还不足以解决业务之间的代码耦合,而组件化是一种能够解决代码耦合、业务工程能够独立运行的技术

  • 这篇文章主要介绍 远程公有库 的创建和管理以及本地索引库的使用

本文以创建 公有库 为例

查看本地索引库

  • 我们用 cocoaPods 的时候,默认使用的是cocoaPods自带的索引库
    终端中使用命令 $ pod repo
1
2
3
4
5
6
7
8
9
10
11
cocoapods
- Type: git (remotes/origin/master)
- URL: https://github.com/CocoaPods/Specs.git
- Path: /Users/mac/.cocoapods/repos/cocoapods

trunk
- Type: CDN
- URL: https://cdn.cocoapods.org/
- Path: /Users/mac/.cocoapods/repos/trunk

2 repos

组件化分类

  • 公有库:所有人都能使用

  • 私有库:公司内部拥有特殊权限才能使用

  • framework:公私都有,动态库/静态库。只能看到 .h 文件。

准备工作

  • 注册 GitHub 账号:上传组件工程用

  • 安装 CocoaPods:创建并验证 pod

  • 安装 Git 命令行 :首次上传组件工程用

  • 安装 Github Desktop 或者 SourceTree:后续更新组件用的,Git命令使用熟练者忽略此项

创建公有库

  • 首先在 Github 创建一个新的 Repository,你的 pods 最终要托管在 Github 平台上的,所以在 Github 上创建一个空的 Repository

注意:库名 = 项目前缀 + 组件名称 ,如 ZJWeakProxy = 解决循环引用组件库

  • 创建完成后的信息如下:

注册 cocoapods 账户

  • 先安装 cocoapods,这个很简单,可以百度搜索自行安装

  • 想要创建一个开源 pod 库,首先我们需要注册 cocoapods账户,基于 cocoapods 已经安装好的前提下,这里直接使用 trunk 去注册 cocopods账户,在终端执行:

1
2
pod trunk register 邮箱地址 '用户名' --verbose
mac@bogon ~ % pod trunk register 13718004742@163.com 'BboyZJ' --verbose

邮箱地址:一般会使用 GitHub邮箱
用户名:随便

  • 注册之后,在邮箱会收到确认邮件

  • 注册成功之后可以在终端 验证是否注册成功
1
2
3
// 验证是否注册成功
mac@bogon ~ % pod trunk me

  • 查看注册信息,以后可以使用该开源pod库发布工具,也可以通过此方式查看已经发布过的pods:
1
2
3
4
5
6
7
8
9
10
11
12
mac@bogon ~ % pod trunk me
- Name: BboyZJ
- Email: 13718004742@163.com
- Since: October 20th, 2021 19:20
- Pods:
- ZJSDKDemo
- ZJSDK_iOS
- Sessions:
- October 20th, 2021 19:20 - March 31st, 2022 04:01. IP: 114.253.15.66
Description: imac
- February 27th, 02:33 - July 5th, 02:37. IP:
114.252.233.188

在本地创建pod库

  • 利用pod命令创建名为 ZJWeakProxypod

注:这个名字要和 GitHub 创建的 Repository 名一致

1
2
3
4
# cd 到桌面文件夹(组件文件夹)ZJComponent目录下,这个不强制随意
mac@bogon ~ % cd ZJComponent
# 执行 pod lib create ZJWeakProxy
mac@bogon ~ % pod lib create ZJWeakProxy

原因分析:一般这是因为服务器的 SSL 证书没有经过第三方机构的签署,所以才报错

解决办法:解除 SSL 验证,再次执行

1
mac@bogon ZJComponent % git config --global http.sslVerify false
  • 执行完上述命令后,会问你几个问题,按需求填写即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 你想使用哪个平台?
1、What platform do you want to use?? [ iOS / macOS ]
iOS
# 库语言选择?
2、What language do you want to use?? [ Swift / ObjC ]
ObjC
# 是否需要一个demo工程,用于调试Pod?
3、Would you like include a demo application with your library? [ Yes / No ]
Yes
# 你要使用哪个测试框架?
4、Which testing frameworks will you use? [ Specta / Kiwi / None ]
None
# 是否要UI测试?
5、Would you like to do view based testing? [ Yes / No ]
NO
# 类名前缀?
6、What is your class prefix?
ZJ
  • 到这里 pod 库就创建完成了,它会自己打开刚才创建的pod库

工程目录介绍

  • 目录结构如下:

【第1部分】:主要是用来编辑pod相关配置元数据区
【第2部分】:主要是用来验证pod效果区
【第3部分】:主要是用来 提供给别人使用暴露出来的pod,ReplaceMe空的可以删除,
是提示我们可以添加自己的类

  • 配置 podspec 本地索引文件
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
Pod::Spec.new do |s|
# 库名称
s.name = 'ZJWeakProxy'
# 版本号
s.version = '0.1.0'
# 库简短介绍
s.summary = 'A short description of ZJWeakProxy.'

# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!

# 开源库描述
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
# 开源库地址,或者是博客、社交地址等
s.homepage = 'https://github.com/BboyZJ/ZJWeakProxy'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
# 开源协议
s.license = { :type => 'MIT', :file => 'LICENSE' }
# 开源库作者
s.author = { 'BboyZJ' => '13718004742@163.com' }
# 开源库资源文件
s.source = { :git => 'https://github.com/BBoyZJ/ZJWeakProxy.git', :tag => s.version.to_s }
# 社交网址
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
# 开源库最低支持
s.ios.deployment_target = '10.0'
# 开源库源文件
s.source_files = 'ZJWeakProxy/Classes/**/*'
# 添加图片等资源文件
# s.resource_bundles = {
# 'ZJWeakProxy' => ['ZJWeakProxy/Assets/*.png']
# }

# s.public_header_files = 'Pod/Classes/**/*.h'
# 依赖系统库 多个用逗号隔开
# s.frameworks = 'UIKit', 'MapKit'
# 引入第三方依赖库
# s.dependency 'AFNetworking', '~> 2.3'
end

注:【s.dependency】:设置依赖三方库或其他组件,多个库可以分开写多次

  • 需要注意如图:

  • Readme 主要是介绍这个组件的用途和使用,可以随时编辑。目前就确认一下自己的名字和邮箱就可以了

  • 协议文件,也是确认一下自己的名字和邮箱就可以了

添加自己的类

  • 打开pod库目录,删除ReplaceMe

  • 创建 ZJWeakProxy 简单类,声明一个打印函数,方便后续测试

注:创建类文件一定要放到 Classes 目录下

.h 文件下:

1
2
3
4
5
#import "ZJWeakProxy.h"

@interface ZJWeakProxy : NSProxy
- (void)printZJWeakProxy;
@end

.m 文件下:

1
2
3
4
5
6
7
#import "ZJWeakProxy.h"

@implementation ZJWeakProxy
- (void)printZJWeakProxy{
NSLog(@"%s",__func__);
}
@end

  • 此时 cdExample 路径下执行 pod install 命令,看看是否能将刚刚添加的库文件引入到工程中
1
2
mac@bogon ~ % cd /Users/mac/Desktop/ZJComponent/ZJWeakProxy/Example 
mac@bogon Example % pod install

如果成功会在Pods中看到:

  • 可以到项目中导入头文件简单使用一下

证明是可用的

【注】:CocoaPods 工具的另外一个优点就是,多个组件依赖同一个组件时,它会自动帮你检测安装,而 不会重复导入

项目上传与发布

  • cd到你的项目路径下,将项目上传到GitHub中(即刚刚创建的ZJWeakProxy公有库中),依次使用下列命令行,不要遗漏
1
2
3
4
5
6
7
8
9
10
11
12
# cd 到 组件ZJWeakProxy路径下
mac@bogon Example % cd /Users/mac/Desktop/ZJComponent/ZJWeakProxy
# 添加github项目路径
mac@bogon ZJWeakProxy % git remote add origin https://github.com/BboyZ/ZJWeakProxy.git
# 添加文件到暂缓区
mac@bogon ZJWeakProxy % git add .
# 将暂存区里的改动提交到本地的版本库并添加注释
mac@bogon ZJWeakProxy % git commit -m "first commit"
# 创建分支main
mac@bogon ZJWeakProxy % git branch -M main
# 提交版本号并push到main分支:第一次提交用 -u,否则去掉
mac@bogon ZJWeakProxy % git push -u origin main
  • 在执行 git push -u origin main 时,如果遇到需要输入用户名和密码:
1
2
Username for 'https://github.com': BboyZJ
Password for 'https://BboyZJ@github.com':

【注意】:这个 密码 不是你 GitHub 的登录密码,而是需要生成一个 access tokens

  • 生成 access token

需要在 GitHub 个人设置页 -> Settings -> Developer Settings -> Personal access tokens 中创建一个 token

  • Generate new token 生成新的 token

设置 token 的有效期 按需设置,访问权限等

  • 选择要授予令牌token的范围或权限

  • 要使用token从命令行访问仓库,请选择repo

  • 要使用token从命令行删除仓库,请选择delete_repo

  • 其他根据需要进行勾选

  • 点击 Generate token 生成 token

ghp_VcqgAmF...ZPJ2IGxu0

【注】:记得把这个 token 保存下来,因为下次再刷新这个页面的时候,你会看不到了

  • 在命令行输入完 token 密码
1
2
3
4
5
6
7
8
9
10
11
12
Username for 'https://github.com': BboyZJ
Password for 'https://BboyZJ@github.com':
Enumerating objects: 91, done.
Counting objects: 100% (91/91), done.
Delta compression using up to 4 threads
Compressing objects: 100% (83/83), done.
Writing objects: 100% (91/91), 29.35 KiB | 2.45 MiB/s, done.
Total 91 (delta 23), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (23/23), done.
To https://github.com/BboyZJ/ZJWeakProxy.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.

由上面看代表上传成功了

打 tag

至此,我们已经成功将本地的仓库关联并推送到远程仓库,现在我们需要发布一个可用的组件

  • 首先我们要给当前项目打一个 tag 版本号,在 podspec 中:
1
s.version           = '0.1.0'
  • 指定的版本号是 0.1.0 ,那么我们就同样打个 0.1.0tag
1
2
3
4
// 打 tag 
mac@bogon ZJWeakProxy % git tag 0.1.0
// 推送到远程
mac@bogon ZJWeakProxy % git push --tags
  • tag 默认在当前分支上,这里只有 master ,所以不用切换分支

验证podspec文件

  • 我们创建的项目以及标签版本号都是沿用了 podspec 文件中的信息,因此可以直接验证 podspec 文件信息是否可以通过验证,podspec 文件的版本号一定要和 tag 保持一致
1
2
// 同时验证本地仓库和远程仓库
mac@bogon ZJWeakProxy % pod spec lint --allow-warnings

【报错】:fatal: unable to access ‘https://github.com/BboyZJ/ZJFPSMonitor.git/ ‘: Empty reply from server

解决办法:

1
mac@bogon ZJFPSMonitor % git config --global http.version HTTP/1.1
  • 如果通过验证,那么你会看到类似下面的提示,绿色的 passed validation

提交到 cocoapods

  • 首先要通过 trunk 注册生成一条会话:
1
2
// pod trunk register 邮箱 用户名 描述
mac@bogon ZJWeakProxy % pod trunk register 13718004742@163.com BboyZJ --description=ZJWeakProxy组件

然后 去邮箱进行验证,验证成功会出现下面页面:

  • 现在,就可以将 podspec 提交给 CocoaPods 了。这个文件将是别人搜索你的组件的索引。
1
mac@bogon ZJWeakProxy % pod trunk push ZJWeakProxy.podspec --allow-warnings

提交成功的结果:

  • pod search 组件名

上传完成之后,接可以通过 pod search ZJWeakProxy 搜索到自己的组件了

如果搜索不到

  • 移除本地缓存的索引文件,命令 :
1
mac@bogon ZJWeakProxy % rm ~/Library/Caches/CocoaPods/search_index.json
  • 更新本地库到最新,命令行:
1
mac@bogon ZJWeakProxy % pod repo update

  • 重新 pod search ZJWeakProxy 产生新的搜索文件,发布新版本则需要打新的 tag,重新编辑 podspec 文件,然后再次提交给 CocoaPods

集成到宿主工程

经过上面的操作我们已经完成了组件的创建和发布,也支持了 Cocoapods 的集成。现在我们需要将该组件集成到宿主工程中去,使用方式和集成三方库是一样的。

  • 新建个带 pod 的项目 Demo,把我们做好的 ZJWeakProxy 加入 podfile 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'

target 'ZJWeakProxy-Demo' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

# ZJWeakProxy
pod 'ZJWeakProxy'

# Pods for ZJWeakProxy-Demo

end
  • 执行 pod install

mac@bogon ZJWeakProxy-Demo % pod install

【问题1】安装报错:[!] Unable to find a specification for ZJWeakProxy

解决办法:

mac@bogon ZJWeakProxy-Demo % pod install --repo-update

【问题2】:HTTP/2 stream 1 was not closed cleanly before end of the underlying stream

解决办法:更改默认通信协议

mac@bogon ZJWeakProxy-Demo % git config --global http.version HTTP/1.1

【问题3】:

解决办法:repo源文件过期了,使用下面的方法更新repo源

1
mac@bogon Example % pod repo update
  • 引入头文件并打印结果

版本更新与维护

  • 现在的 ZJWeakProxy 库已经在GitHub上托管了,以后维护这个项目就可以了(开始本地创建的ZJWeakProxy项目就可以删除了),管理GitHub仓库,有两种方案:

    • 可以使用命令行 git clone https://github.com/BboyZJ/ZJWeakProxy

    • 也可以使用 GitHub Desktop

      • 下载 GitHub Desktop 登录你的用户名和密码,File -> Responsitory
  • 其实 GitHub Desktop 更加可视化一些,上面History就是刚才git命令行的记录

总结

终于写完了,哇哦😮!

  • Post title:OC组件化06:【方案二】cocoapods组件化
  • Post author:张建
  • Create time:2023-03-04 23:30:55
  • Post link:https://redefine.ohevan.com/2023/03/04/OC组件化/OC组件化06:【方案二】cocoapods组件化/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.