序言
经过长时间的使用实践,发现静态包使用率不高,所以这个解决方案现已弃用。
介绍
考虑到代码编译时间,我在构建组件化过程中引入了静态包方案,即每一个Pod库都支持源码和静态包两种安装方式。
这不但需要修改*.podspec
文件来支持,还须要在每次发布前编译静态包。
开发过程变得比较繁琐,为了方便开发,我对官方模版做了一点优化,发布了Pod-Template,还写了一个命令行工具 Pod-Pipeline 来简化发布操作。
Pod-Template介绍
- 结构改动
- 由于我暂时没有进行swift为主的Pod库开发。所以我删掉了模版中的swift内容。
- 由于我希望Pod库支持静态包。所以我移除了Podfile中的
use_frameworks!
- 由于Pod内容和编译内容较多,且不是必要保存内容。所以在
.gitignore
文件中添加了Pods/
和${POD_NAME}-*/
两个默认忽略项。- 由于静态包的二进制文件无法被Git识别内容变化,每次都直接上传的话会让Git仓库变得很大。所以我引入了Git LFS(Large File Storage),并在项目中添加了
.gitattributes
文件。但是须要使用者自己在设备中安装Git LFS,并在项目中执行git lfs install
。
- 通用Pod库的
*.podspec
中关于资源、代码引用的改动
我们在执行
pod install
的时候,实际是从本地的pod cache
中寻找对应的库进行安装,所以在Spec
中必须同时包含源码版本和静态包版本。
我选择使用subspec:SourceMode
和subspec:FrameworkMode
来承载两种版本的内容,并由subspec:Core
解析执行pod install
时传入的FX=all(或dependency)
参数,判断安装时应该使用哪种版本。
Pod::Spec.new do |s|
...
#静态包模式
s.subspec 'FrameworkMode' do |fm|
fm.vendored_frameworks = '${POD_NAME}/${POD_NAME}SDK/*.framework'
# fm.resource = '${POD_NAME}/${POD_NAME}SDK/*.bundle'
end
#源码模式
s.subspec 'SourceMode' do |sm|
sm.source_files = [
'${POD_NAME}/Classes/**/*'
]
sm.public_header_files = [
'${POD_NAME}/Classes/**/*.h'
]
# sm.resource_bundles = {
# '${POD_NAME}' => ['${POD_NAME}/Assets/**/*.png']
# }
end
#核心代码
s.subspec 'Core' do |core|
# FX=all pod install; 所有库都使用framework模式安装
isAllFX = ENV['FX'] == "all" || ENV['${POD_NAME}_FX'] == "all";
# FX=dependency pod install; 依赖库使用framework模式安装
isDependencyFX = ENV['FX'] == "dependency" || ENV['${POD_NAME}_FX'] == "dependency";
isDependency = !!__FILE__[".cocoapods/repos"];
if isAllFX || (isDependency && isDependencyFX)
core.dependency '${POD_NAME}/FrameworkMode'
else
core.dependency '${POD_NAME}/SourceMode'
end
# core.public_header_files = 'Pod/Classes/**/*.h'
# core.frameworks = 'UIKit', 'MapKit'
# core.dependency 'AFNetworking', '~> 2.3'
# core.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-ObjC' }
end
s.default_subspec = 'Core'
end
- 业务组件Pod库的
*.podspec
中关于资源、代码引用的改动
由于业务组件之间可能会互相调用
对外接口
,而并不需要引用完整Pod库。
所以我把对外接口
的声明文件(即TKModule+*.h
文件)单独封装为subspec:Interface
。
而对外接口
的实现内容(即TKModule+*.m
文件)依然要添加到subspec:SourceMode
。
此外,使用者可能并未在本地声明本业务组件的对外接口
,所以安装源码版本时应该同时安装subspec:Interface
。
至于静态包版,它本就是由源码版本编译得来的,所以其中已经包含了对外接口
的声明文件。
Pod::Spec.new do |s|
...
#源码模式
s.subspec 'SourceMode' do |sm|
sm.source_files = [
'${POD_NAME}/Classes/**/*',
'${POD_NAME}/Interface/**/*.m'
]
...
end
#对外接口
s.subspec 'Interface' do |interface|
interface.source_files = [
'${POD_NAME}/Interface/**/*.h',
]
interface.public_header_files = [
'${POD_NAME}/Interface/**/*.h'
]
end
#核心代码
s.subspec 'Core' do |core|
...
if isAllFX || (isDependency && isDependencyFX)
core.dependency '${POD_NAME}/FrameworkMode'
else
core.dependency '${POD_NAME}/SourceMode'
core.dependency '${POD_NAME}/Interface'
end
...
end
s.default_subspec = 'Core'
end
- 为刚创建的Pod库添加本地配置
通过我的模版创建的Pod库,在进行开发前须要添加一些本地配置。当然也可以使用自己的模版去避免了这些手动操作。
- 添加Git仓库的远程映射
$ git@github.com:xxx/xxx.git
- 为Git仓库安装Git LFS
$ git lfs install
- 修改podspec中的本地配置
Pod::Spec.new do |s| s.summary = 'XXX' s.description = 'XXXX' s.homepage = 'https://github.com/xxx/xxx' s.source = { :git => 'https://github.com/xxx/xxx.git', :tag => s.version.to_s }
- 在Podfile中添加私有的Specs地址
source 'https://github.com/xxxx/Specs.git'
Pod-Pipeline介绍
该工具整合了Git和CocoaPods的一些功能,可以帮助我更简单地构建和发布项目。
#安装
$ gem install pod-pipeline
Pod-Pipeline和CocoaPods都是基于CLAide(Comand Line aide)实现命令行功能的,所以基本用法是一致的,很容易上手。
$ ppl --help
Usage:
$ ppl COMMAND
Pod-Pipeline 是 CocoaPods 的流水线工具.
Commands:
+ build 项目构建
+ new 创建新项目
+ publish 项目发布
+ scan 项目扫描
+ update 项目更新
Options:
--help 展示改命令的介绍面板
通常用法:
- 是在完成需求开发并提交修改后。
- 在Demo目录执行
pod install
,保证Demo对Pod库源码引用正常。- 在Pod目录执行下方命令
$ ppl publish\ --repo=xxx\ --build-arch=arm64,armv7\ --build-combine=local\ --update-channel=version,git\ --repo-push-sources=https://github.com/xxxx/Specs.git\ --repo-push-allow-warnings
第2步中生成的
Podfile.lock
改动,会在ppl update git
命令执行过程中和*.podspec
的改动一同提交