iOS 私有库模块产物化及托管服务器
目的
为减少编译时间和打包时间,将私有库模块预编译成framework包引入工程,并使用脚本实现模块自动升级、和产物化托管。
一、模块生成framework包
使用打包工具cocoapods-packager ,具体下载方法和使用方法点击链接可查看。
为了先保证打包成功之后,才更新版本到私有库,使用本地代码仓库进行打包。将打包所用podspec需要与私有库podspec区分开。
以EMPAppstore模块举例:私有库podspec:EMPAppStore.podspec;打包所需podspec:EMPAppStorePackage.podspec
EMPAppStorePackage.podspec内容:
1 | require 'etc' |
打包脚本package.h内容
1 | pod package EMPAppStorePackage.podspec --force --embedded --no-mangle --exclude-deps --spec-sources=[私有库repo地址],https://github.com/CocoaPods/Specs.git |
错误及解决方法
1 | have the same architectures (arm64) and can't be in the same fat output file |
原因:XCode12 编译的模拟器库新增支持架构arm64,和真机模拟器的arm64格式冲突。
解决方法:
- 在packagePodspec中增加target的配置:
1 | s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } |
仍然出现错误的话
- 修改cocoapods-packager的源码:
源码路径(注意gem版本和cocoapods-packager版本):
/Library/Ruby/Gems/2.6.0/gems/cocoapods-packager-1.5.0/lib/cocoapods-packager/
修改pod_utils.rb文件 添加一行
二、模块产物化的托管
两种方案
生成的framework包直接放在源码仓库中
问题:每次更新一个版本都会在源码仓库中增加一个framework包,导致源码仓库占用内存随版本更新不断增大,会导致两个问题:
- 长此以往,gitee上仓库硬盘容量不足
- 浪费组内成员更新仓库所需的时间
既然cocoapods支持zip包的下载方式。干脆把framework包压缩后托管在服务器上。
但是我们现有的模块比较多,如果都在自己电脑上做升级打包,要手动打包、上传还要时刻盯着结果。那就在服务器上部署个jenkins来完成打包的任务,打包压缩完成之后借助nginx托管。
jenkins配置上gitee仓库的webhook。
jenkins配置如下
自动更新版本打包的脚本如下:
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194自动打包frameWork并推送pod repo的脚本。可指定版本号,不指定版本号按照版本号自增1的规则更新。
流程如下:
更新代码
更改[moduleName]Package.podspec 版本号
执行打包命令
修改[moudule].podspec 版本号
git add、commit、push
git tag 、 git push --tags
执行更新命令xx
当前文件路径
directory="$(pwd)"
当前模块名称
mouduleName=${directory##*/}
echo "当前模块名称 ${mouduleName}"
版本号递增函数
increment_version ()
{
declare -a part=( ${1//\./ } )
declare new
declare -i carry=1
CNTR=${#part[@]}-1
len=${#part[CNTR]}
new=$((part[CNTR]+carry))
part[CNTR]=${new}
new="${part[*]}"
echo "${new// /.}"
return ${new// /.}
}
echo "当前分支"
git branch
echo "更新当前分支代码"
git pull origin
echo "更新当前分支代码完成"
read -p "输入需要发布的版本号,按Enter默认版本最小位+1: " shouldToVersion
echo "输入版本号为:${shouldToVersion}"
read -p "输入tag的注释(当前版本更新内容),按Enter表示不需要tag注释: " tagComment
echo "输入版本更新内容:${tagComment}"
shouldToVersion=""
tagComment=""
echo "获取podspec文件 begin"
podspec文件路径
packagePodspec_file_path="../${mouduleName}Package.podspec"
podpushPodspec_file_path="../${mouduleName}.podspec"
packagePodspec_file_name="${mouduleName}Package.podspec"
podpushPodspec_file_name="${mouduleName}.podspec"
echo "packagePodspec_file_path: ${packagePodspec_file_path}"
echo "podpushPodspec_file_path: ${podpushPodspec_file_path}"
echo "获取podspec文件 end"
echo "读取podspec文件内容 begin"
定义pod文件名称
pod_file_name=${packagePodspec_file_name}
查找 podspec 的版本
search_str="s.version"
当前版本号
currentVersion=""
版本号所在行内容
versionLine=""
while read line
do
#查找包含的内容,正则表达式以search_str开头的内容
result=$(echo ${line} | grep "^${search_str}")
if [ "$result" != "" ]
then
echo " ${line} 包含 ${search_str}"
versionLine=${line}
currentVersion=${result##* }
#去掉双引号
currentVersion=${currentVersion:1:${#currentVersion}-1}
currentVersion=${currentVersion:0:${#currentVersion}-1}
fi
done < $pod_file_name
echo "当前版本号: ${currentVersion}"
if [ currentVersion == "" ]
then
echo "获取当前版本号错误"
set -e
exit 1
fi
if [ "$shouldToVersion" == "" ]
then
shouldToVersion=$(increment_version ${currentVersion})
#shouldToVersion=${currentVersion}
fi
echo "更新版本号为:$shouldToVersion"
updateVersionLine="s.version = \"${shouldToVersion}\""
echo "修改packagePodspec版本号 begin"
sed -i "" "s/${versionLine}/${updateVersionLine}/g" ${packagePodspec_file_name}
echo "修改packagePodspec版本号 end"
echo "打包 begin"
sh package.sh
if [ ! -d "${mouduleName}-$shouldToVersion/${mouduleName}.xcframework" ] && [ ! -d "${mouduleName}-${shouldToVersion}/ios/${mouduleName}.embeddedframework" ]
then
echo "打包失败"
set -e
exit 1
fi
echo "打包 end"
echo "删除build文件夹"
rm -rf "${mouduleName}-$shouldToVersion/build"
zipVersion=${shouldToVersion//./_}
zipName="${mouduleName}_v${zipVersion}"
rm -rf ${zipName}/
rm -f ${zipName}.zip
mkdir ${zipName}
mkdir ${zipName}/frameworks
mkdir ${zipName}/libs
echo " 创建压缩包"
if [ -d "${mouduleName}-$shouldToVersion/${mouduleName}.xcframework" ]
then
echo "cocoapods-xcframework打包方式"
cp -a -f ${mouduleName}-${shouldToVersion}/${mouduleName}.xcframework/ios-armv7_arm64/ ${zipName}/frameworks/
# macmini not work , user find command
# cp -rf ${mouduleName}/Core/Vendor/**/*.framework ${zipName}/frameworks/
# cp -rf ${mouduleName}/Core/Vendor/**/*.a ${zipName}/libs/
# cp -rf EMPASR/Resources/**/*.{bundle,dat,bin,caf} ${zipName}/
find ${mouduleName}/Resources/ -name '*.bundle' -o -name '*.dat' -o -name '*.bin' -o -name '*.caf' -o -name '*.xml' -o -name '*.js' -o -name '*.plist' | xargs -I F cp -rf "F" ${zipName}/
# 第三方库资源文件
find ${mouduleName}/Core/Vendor -name '*.bundle' -o -name '*.dat' -o -name '*.bin' -o -name '*.caf' -o -name '*.xml' -o -name '*.js' -o -name '*.plist' | xargs -I F cp -rf "F" ${zipName}/
else
echo "cocoapods-packer打包方式"
cp -a -f ${mouduleName}-${shouldToVersion}/ios/${mouduleName}.embeddedframework/*.framework ${zipName}/frameworks/
#find ${mouduleName}/Resources/ -name '*.bundle' -o -name '*.dat' -o -name '*.bin' -o -name '*.caf' -o -name '*.xml' | xargs -I F cp -rf "F" ${zipName}/
# 第三方库资源文件
#find ${mouduleName}/Core/Vendor -name '*.bundle' -o -name '*.dat' -o -name '*.bin' -o -name '*.caf' -o -name '*.xml' -o -name '*.js' -o -name '*.plist' | xargs -I F cp -rf "F" ${zipName}/
fi
echo "导入依赖的第三方库"
find ${mouduleName}/Core/Vendor/ -name '*.framework' | xargs -I F cp -rf "F" ${zipName}/frameworks/
find ${mouduleName}/Core/Vendor/ -name '*.a' | xargs -I F cp -rf "F" ${zipName}/libs/
zip -y -r ${zipName}.zip ${zipName}
echo "上传压缩包"
sshpass -p 'cccc' ssh xiaofeixia@192.168.50.197
sshpass -p 'cccc' scp ${zipName}.zip xiaofeixia@192.168.50.197:/Users/xiaofeixia/ios_frameworks/${mouduleName}
if [ ! -d "/Users/mac/Desktop/iOS/ios-frameworks/${mouduleName}" ]
then
mkdir /Users/mac/Desktop/iOS/ios-frameworks/${mouduleName}
echo "创建模块文件夹"
fi
cp ${zipName}.zip /Users/mac/Desktop/iOS/ios-frameworks/${mouduleName}
echo "删除包文件"
rm -rf ${mouduleName}-${shouldToVersion}
rm -rf ${zipName}/
rm -f ${zipName}.zip
echo "修改podspec版本号 begin"
sed -i "" "s/${versionLine}/${updateVersionLine}/g" ${podpushPodspec_file_name}
echo "修改podspec版本号 end"
echo "git push"
git add ${packagePodspec_file_name} ${podpushPodspec_file_name}
git commit -m "version to $shouldToVersion"
git push origin HEAD:master
echo "git tag"
git tag -f $shouldToVersion -m "$tagComment"
git push origin -f $shouldToVersion
echo "pod push"
if ! sh podpush.sh; then
echo "pod install错误"
set -e
exit 1
fi
echo "更新pod私有库"
cd /Users/mac/.cocoapods/repos/EMPPrivateSpecs
git pull三、总结
本文章只是提供了iOS模块产物化、自动升级托管的一个大致流程及思路。具体实现细节视个人项目而定。