iOS ipa重签名 (个人版、企业版APP均可)
本文的实现方案包括脚本参照的是简书的一篇文章ios打渠道包,根据我项目中的实际情况做了修改,在此记录一下整个实现过程。
**重签名:**可以让用个人开发者账号打出来的包,不用上架Appstore即可将其安装到iOS设备上(前提条件是你得有一个开发者证书)。
**风险提示:**这种重签名方法仅供个人有兴趣的开发者去玩玩,不提倡用于商用,提倡使用Appstore上传发布到你的应用,重签名只能算是黑科技,苹果所不提倡的东西,如果APP使用量过大的话,企业证书有被封停的风险。当然,如果你使用的是个人开发者账号,则只能在添加了UUID的设备上面安装
苹果在iOS8.1.3系统以后加强了对ipa安装包签名的验证,主要区别在于ipa唯一标识在原有Bundle Identifier的基础上增加了证书ID,也就说安装包和手机上已安装APP的Bundle Identifier即使一致,如果两者签名的证书ID不相同,那么安装包也无法正常安装。
图中方框里字符串就是证书ID(钥匙串中我的证书),升级后的ipa标识就是证书ID+BundleID,只有两者完全匹配,安装包才能覆盖安装,否则就会提示安装失败。解决办法就是卸载安装包,重新安装!
如果这个地方找不到证书ID,可登录到苹果开发者中心https://developer.apple.com,memberCenter,点击certificates,identifier&Profiles,再点击identifier中的App IDs点击某个AppId(因为证书ID是唯一的,所以选哪个APPID都是一样的)
其中Prefix就是证书ID
目前,重签名主要用于企业证书重签名个人证书发布的ipa包,包括各种助手及企业内测包的发布等。在重签名前,让我们先看看一个完整的ipa包有哪些与证书相关的东西!将ipa包后缀名改为zip,解压之后,会发现一个文件夹Payload(如果是个人证书打包还会包含Symbols文件夹),payload文件夹下面的XXX.app文件夹中有_CodeSignature签名文件夹和embedded.mobileprovision证书配置文件以及其他资源文件。重签名只关注这两个文件即可。
_CodeSignature -> ipa包签名文件
embedded.mobileprovision -> 证书配置文件
so,替换上面两个文件就解决了ipa重签名的主要问题。
替换_CodeSignature里面的签名文件需要用到一个文件entitlements.plist的授权文件, 所以我们要创建一个entitlements.plist文件( 这里我没有找到, 我就重新创建了一个, 后面说)
首先,我的需求是,在手上已有ipa安装包,也就是母包的情况下,修改母包中的某个文件中作为渠道号的值,生成新的ipa安装包,也就是带有渠道号的渠道包。
这是已经打包成功导出的 ipa包:
ipa包,我们可以视为一个压缩包,使用解压工具对其解压可以得到一个名叫Payload的文件夹:
Payload文件夹中是一个.app文件,右键显示包内容可以看到其中的文件:
其中的DChannel.plist文件就是在母包打包之前在Xcode工程中新建的,用于存储渠道号等信息,我在这个plist文件中设置了叫Channel的字段,可以随意给一个默认值。之后我们在给母包打渠道号时,就是要修改plist文件中的Channel值,修改后重新压缩Payload文件夹生成渠道包,此时渠道包运行后,程序中获取的Channel值就变成了对应的渠道号。
下面是操作步骤:
准备文件:
application-identifier
xxxxxxxxxx.com.xxx.xxx
com.apple.developer.team-identifier
xxxxxxxxxx
get-task-allow
keychain-access-groups
xxxxxxxxxx.com.xxx.xxx
2.ChannelPackage.sh:
#!/bin/bash
# 1. 这里面的包名需要传过来, 作为一个工具类
# 2. 修改的取到标识也可以作为参数传进来, 我这里直接写死了
# 3. 这里的 Dchannel.plist 文件我这里是我区分渠道的标识, 修改为你需要的
# 4. 使用的话, 需要修改 shell 脚本的地方,① Dchannel.plist ② ChannelID ③ Distribution证书
# 5. 成功了, 上传 fir 或者蒲公英测试一把吧
# 6. 还是不懂的话 qq:249804175 直接滴滴我
# 输入的包名
name=$1
# $1 就是传进来的第一个参数 $2就是第二个参数
#echo 是打印的意思
echo "---ahh---"
echo ${name}
appName="${name}.app"
echo ${appName}
plistBuddy="/usr/libexec/PlistBuddy"
#configName="channel.plist"
configName="Payload/${appName}/DChannel.plist"
configNameNew="Payload"
ipa="${name}.ipa"
# 打好包后输出的文件夹名字
outUpdateAppDir="OutApps"
# 获取当前目录,并切换过去
currDir=${PWD}
echo ${currDir}
cd "${currDir}"
echo "-----${currDir}"
# 生成日志目录
#mkdir log
rm -rf Payload
#解压缩
unzip -o -q ${ipa} #>> log/unzipUpdateApp.log
#echo `ls Payload`
# 删除旧的文件,重新生成
rm -rf "${outUpdateAppDir}"
mkdir "${outUpdateAppDir}"
echo "------------------------开始打包程序------------------------"
#echo ""
# 渠道列表文件开始打包
#for line in $(cat TargetChanelList.txt)
#循环数组,批量打包时需要修改的渠道号和渠道Id ("1174" "1173")
# 这里的参数可以从外面直接传过来,
ChannelID=("111" "222" "333")
echo ${#ChannelID[@]}
for ((i=0;i<${#ChannelID[@]};i++))
do
#echo是输出命令,可以忽略
echo "........正在打包渠道号:${ChannelID[$i]}"
# cd Payload/${appName}
# 设置Channel.plist
echo "-----1----${PWD}"
#修改
$plistBuddy -c "set :Channel ${ChannelID[$i]}" ${configName}
echo "-----2----${PWD}"
rm -rf Payload/${appName}/_CodeSignature
#cp AdHoc配置文件 替换 Payload/${appName}文件下的embedded.mobileprovision
cp embedded.mobileprovision "Payload/${appName}/embedded.mobileprovision"
# ipa包签名: codesign -f -s "iPhone Distribution: Distribution证书名字,打开钥匙串可以看到" --entitlements "Entitlements.plist" "Payload/${appName}"
codesign -f -s "iPhone Distribution: Distribution证书名字,打开钥匙串可以看到" --entitlements entitlements.plist Payload/DEMO.app
#Payload/Demo.app: replacing existing signature :这个时候是已经OK
zip -rq "${outUpdateAppDir}/${ChannelID[$i]}.ipa" "Payload"
echo "........打包已完成"
done
echo "------------------------程序打包已结束------------------------"
点击查看参考一
点击查看参考二