一、背景
背景1、文章《Shell应用场景1 ~ iOS自动化SDK封装详细教程》介绍了打包真机版本sdk和模拟器版本sdk,两个版本提供给第三方使用的时候很不方便,这个时候我们就需要考虑合成一个全的sdk。
背景2、如果我们在使用一些第三方提供的sdk的时候,真机和模拟器是分开的,这个时候我们也可以进行合成再使用。
二、真机包和模拟器包合成必要性
如果不合成,我们在使用的时候可能会遇到以下问题:
1、每次升级都需要去替换两个位置的文件,很容易出现只替换了模拟器,真机没有替换,导致模拟器调试正常,而发包之后还是有问题存在。
2、使用的时候也很麻烦。
项目里只添加模拟器版本sdk,进行模拟器调试。 在真机调试或者打包的时候再去替换真机版本的sdk,这种会每次切换设备的时候,都会浪费一些时间重复做替换的工作。
总而言之就是2个版本的存在,造成很多麻烦。如果合成一个包,这样我们用起来就会很方便,不会去考虑模拟器怎么样,真机又怎么样,我们不需要关系模拟器和真机,只需要关系这个包是不是最新的就可以。
三、利用脚本合成的优势
手动合成的话,我们需要进行以下操作:
1、执行lipo -create
2、拷贝合成的执行文件,替换到真机版本的sdk
3、swift语言开发的sdk,还需要手动去拷贝模拟器版本的XXX.framework/Modules下的文件,全部合并到真机版本sdk中。
4、swift语言的版本sdk,还需要手动找到模拟器下的Headers/XXX-Swift.h文件内容合并到真机版本中。
5、将替换好的真机版本sdk拿走使用
脚本自动化,我们只需要执行一步操作即可,就是:
1、修改模拟器sdk路径,真机sdk路径,运行脚本。等待输出结果。
从以上操作步骤对比来看,手动每一次的合成都需要进行繁琐的步骤,而使用脚本的话,就会很方便的生成一个合并sdk。步骤简化的同时,避免了一些错误的发生。
四、实现目标
1、确保模拟器sdk存在。
2、确保真机sdk存在
3、自动合成最终完整的、正常的、需要的sdk。
4、支持OC、Swift
五、解决步骤
5.1、设置必要参数
#1、脚本当前路径
Script_Path=`pwd`
#2、framework name
sdk_Name="XESTestSDK"
#3、模拟器framework所在目录
iphonesimulatorPath="$Script_Path/buildFrameworkTemp/Release-iphonesimulator"
#4、真机framework所在目录
iphoneosPath="$Script_Path/buildFrameworkTemp/Release-iphoneos"
#5、合成文件夹存放目录
mergePath="$Script_Path/mergePath"
#6、是否是swift语言项目, 1,0
isSwift=1
5.2、创建Swift语言项目特殊处理方法
#Swift语言项目特殊处理
swiftHandle(){
#1、将模拟器framework下面的Headers/${sdk_Name}-Swift.h 内容复制到,目标位置上去
iphonesimulatorSwiftTxt=${iphonesimulatorPath}/${sdk_Name}.framework/"Headers/${sdk_Name}-Swift.h"
mergeSwiftTxt=${mergePath}/${sdk_Name}.framework/"Headers/${sdk_Name}-Swift.h"
# echo "iphonesimulatorSwiftTxt=======$iphonesimulatorSwiftTxt"
# echo "mergeSwiftTxt=======$mergeSwiftTxt"
if [[ -e ${iphonesimulatorSwiftTxt} ]]; then
cat $iphonesimulatorSwiftTxt | while read line
do
echo "$line" >> $mergeSwiftTxt
done
echo "\nswift头文件合成完成=======swift头文件合成完成"
else
echo "\niphonesimulatorSwiftTxt=======不存在"
fi
#2、将模拟器framework下的Modules/${sdk_Name}.swiftmodule 文件夹覆盖到目标对应位置
cp -r ${iphonesimulatorPath}/${sdk_Name}.framework/"Modules/$sdk_Name.swiftmodule" ${mergePath}/${sdk_Name}".framework/Modules"
echo "\nModules文件夹合成完成=======Modules文件夹合成完成"
echo "\n===================== Swift项目特殊处理完成 ======="
}
5.3、创建合成方法
#合成方法
mergeStart(){
#判断合成目标文件夹是否存在,存在则删除
if [[ -d ${mergePath} ]]; then
rm -rf ${mergePath}
fi
#创建目标文件夹
mkdir -p ${mergePath}
#合成模拟器和真机包,
#1、Release-iphoneos/XESTestSDK.framework/XESTestSDK
#2、Release-iphonesimulator/XESTestSDK.framework/XESTestSDK
#3、1+2=mergePath/XESTestSDK
lipo -create ${iphonesimulatorPath}/${sdk_Name}.framework/${sdk_Name} ${iphoneosPath}/${sdk_Name}.framework/${sdk_Name} -output ${mergePath}/${sdk_Name}
#将真机版本的framework拷贝到目标文件夹
cp -av ${iphoneosPath}/${sdk_Name}.framework ${mergePath}
#将目标文件下合成的执行文件,拷贝到目标下的framework内
mv -fv ${mergePath}/${sdk_Name} ${mergePath}/${sdk_Name}.framework/${sdk_Name}
#检验最后合成的framework支持的架构
lipo -info ${mergePath}/${sdk_Name}.framework/${sdk_Name}
if isSwift==1; then
#swift语言的项目,特殊处理
swiftHandle
else
echo "\n=====================当前不是 Swift项目 ======="
fi
echo "\n>>>>>>>>>>>>>>>> 合并完成!!!\n"
}
5.4、脚本默认执行代码
#打印几个路径,方便确认路径是都都设置正确
echo "iphonesimulatorPath:$iphonesimulatorPath"
echo "iphoneosPath:$iphoneosPath"
echo "mergePath:$mergePath"
#判断模拟器framework是否存在
iphonesimulatorSDK=${iphonesimulatorPath}/${sdk_Name}".framework"/${sdk_Name}
echo "\niphonesimulatorSDK:$iphonesimulatorSDK"
if [[ -e ${iphonesimulatorSDK} ]]; then
#echo ">>>>>>>>>>> iphonesimulatorPath 存在!!!!!!!!!"
#检验模拟器framework支持的架构
lipo -info ${iphonesimulatorSDK}
else
echo "\n>>>>>>>>>>> iphonesimulatorPath 不存在!!!!!!!!!"
exit [0]
fi
#判断真机framework是否存在
iphoneosSDK=${iphoneosPath}/${sdk_Name}".framework"/${sdk_Name}
echo "\niphoneosSDK:$iphoneosSDK"
if [[ -e ${iphoneosSDK} ]]; then
#echo ">>>>>>>>>>> iphoneosPath 存在!!!!!!!!!"
#检验真机framework支持的架构
lipo -info ${iphoneosSDK}
else
echo "\n>>>>>>>>>>> iphoneosPath 不存在!!!!!!!!!"
return
fi
#调用合成方法
mergeStart
5.5、脚本解析说明
- echo命令
- 1.1 显示普通字符串
echo "shell脚本演示demo"
- 1.2 显示变量
textS="shell脚本演示demo"
echo "${textS} 666"
- 1.3 显示换行
echo "shell脚本 \n 演示demo"
- 1.4 显示一个执行命令,执行结果是获取到系统时间
echo `date`
- 退出命令
语法:exit 状态->退出程序
exit [0]
- 条件判断
判断文件是否存在
if [[ -e ${iphonesimulatorSDK} ]]; then
#echo ">>>>>>>>>>> iphonesimulatorPath 存在!!!!!!!!!"
#检验模拟器framework支持的架构
lipo -info ${iphonesimulatorSDK}
else
echo "\n>>>>>>>>>>> iphonesimulatorPath 不存在!!!!!!!!!"
exit [0]
fi
其中文件表达式有以下几种表达方式
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
- 检验模拟器framework支持的架构
语法:lipo -info 执行文件完成路径名称
lipo -info ${iphonesimulatorSDK}
- 判断合成目标文件夹是否存在,存在则删除
if [[ -d ${mergePath} ]]; then
rm -rf ${mergePath}
fi
- 创建文件夹
mkdir -p ${mergePath}
- 模拟器和真机包
语法:lipo -create 真机执行文件路径 模拟器执行文件路径 -output 输出目录
lipo -create ${iphonesimulatorPath}/${sdk_Name}.framework/${sdk_Name} ${iphoneosPath}/${sdk_Name}.framework/${sdk_Name} -output ${mergePath}/${sdk_Name}
- 拷贝方法
#将真机版本的framework拷贝到目标文件夹
cp -av ${iphoneosPath}/${sdk_Name}.framework ${mergePath}
#将目标文件下合成的执行文件,拷贝到目标下的framework内
mv -fv ${mergePath}/${sdk_Name} ${mergePath}/${sdk_Name}.framework/${sdk_Name}
cp:复制文件
mv:移动文件,剪切
后面跟的参数,介绍如下:
|参数|描述|
|-|-|-|
|-a| 归档文件,并保留它们现在的属性(linux文件归档的意思是为文件或目录备份,建立归档文件)
|-b| 创建已存在目录文件的备份,而非覆盖它
|-d| 保留
|-f| 强制覆盖已存在的目标文件,不提示
|-i| 在覆盖目标文件之前提示
|-l| 创建文件链接而非复制文件
|-p| 如果可能保留文件属性
|-r| 递归的复制文件
|-R| 递归的复制目录
|-s| 创建一个符号链接而非复制文件
|-S| 覆盖默认的备份文件的后缀(默认是~)
|-u| 仅在源文件比目标文件新的情况下复制(相当于更新)
|-v| 详细模式,解释到底发生了什么
|-x| 仅限于当前文件系统的复制(这句话的背景是:Linux可同时挂在多个不同的文件系统类型的存储设备)
- 检验framework的执行文件支持的架构
语法:lipo -info 执行文件完整路径
#检验最后合成的framework支持的架构
lipo -info ${mergePath}/${sdk_Name}.framework/${sdk_Name}
- 读取文件,一行行输出,输出内容写入到另一个文件内
cat $iphonesimulatorSwiftTxt | while read line
do
echo "$line" >> $mergeSwiftTxt
done
iphonesimulatorSwiftTxt、mergeSwiftTxt 都是文件路径,这段代码意思是将iphonesimulatorSwiftTxt的内容一行行读出来追加写入到mergeSwiftTxt内。
您可能感兴趣的文章:
Shell应用场景1 ~ iOS自动化SDK封装详细教程
网友评论