灰度测试包应该和正式包的内容完全一致,只是添加了一些辅助的开关,例如:可以进调试服务器、可以输入gm指令、可以下载测试url的cdn热更资源。如果开发都打两个包的话就很麻烦。日后游戏上线后我们需要,dsym和带符号表的so用来还原闪退的堆栈。Android只是编译unity的时候会生成il2cpp.so.debug,iOS则每次编译Xcode会生成。所以理想化的灰度测试包和正式测试包,最好可以共享一份符号表的so和dsym,或者灰度测试包和正式包是同一个包。
目前有2个方案(如果有更好的方案欢迎大家在下面补充)
1.判断网络状态,如果连接了特定的网络,例如公司的wifi,就是灰度测试包,没连公司网络则属于正式包。
获取wifi名
Android Java代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * 获取连接wifi的信息 * @return 表示wifi名 */ private static WifiManager wifi; static public String GetWifiName() { if(wifi==null){ wifi = (WifiManager) mActivity.getSystemService(Context.WIFI_SERVICE); } String ssid =wifi.getConnectionInfo().getSSID(); return (ssid!=null)?ssid.replace("\"",""):""; } |
IOS oc代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/** * 获取连接wifi的信息 * @return 表示wifi名 */ char* CS_GetWifiName() { NSLog(@"KL GetWifiName"); NSString *name=@""; NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces(); if(ifs != nil && ifs.count >= 1){ NSString *ifnam = ifs[0]; NSString *ssid = ((__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam))[@"SSID"]; if(ssid!=nil){ name=ssid; } } return [name cStringUsingEncoding:NSUTF8StringEncoding]; } |
接着在c#代码中获取wifi连接内网的ip
string ip = Network.player.ipAddress
通过wifi名和ip两个即可锁定网络状态。
2.利用apktool 和 codesign 修改ipa和apk中的一个配置信息后重新打包,因为是直接操作游戏包所以打包会非常快。
AndroidManiest.xml中添加一行
1 2 3 4 5 |
<!--灰度测试标识--> <meta-data android:name="gray.test" android:value="release" /> <!--灰度测试标识--> |
ios info.plist中加一行
1 2 3 4 |
<key>gray.test</key> <string>release</string> |
灰度测试包就是把ipa和apk里面的这个值改了重新打包,程序中代码会去取这个值来做逻辑判断是否灰度测试包。
Android修改AndroidManiest.xml后重新打包
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 |
#BUILD_EXPORT_PROJECT unity导出的android工程 #BUILD_OUTPUT_APK jenkins自动打包后,把apk放在BUILD_EXPORT_PROJECT目录下 #APK_TOOL apktool.jar的目录 #BUILD_TOOL_ZIPALIGN zipalign的路径,在android sdk中 #证书名 别名 密码 重新签名 #BUILD_KEYSTORE_NAME #BUILD_KEYALIAS_NAME #BUILD_KEYSTORE_PASS if [[ -f "${BUILD_OUTPUT_APK}" ]]; then apkdir=$(basename $BUILD_OUTPUT_APK .apk) cd ${BUILD_EXPORT_PROJECT} if [[ -d "${apkdir}" ]]; then rm -rf "${apkdir}" fi java -jar "${APK_TOOL}/apktool_2.2.4.jar" d ${BUILD_OUTPUT_APK} sed -i.bu -e "s/<meta-data android:name=\"gray.test\" android:value=\"release\"/<meta-data android:name=\"gray.test\" android:value=\"debug\"/" $apkdir/AndroidManifest.xml java -jar "${APK_TOOL}/apktool_2.2.4.jar" b ${apkdir} jarsigner -sigalg SHA1withRSA -digestalg SHA1 -sigfile CERT -keystore "${BUILD_KEYSTORE_NAME}" -storepass "${BUILD_KEYSTORE_PASS}" "${apkdir}/dist/${apkdir}.apk" "${BUILD_KEYALIAS_NAME}" "${BUILD_TOOL_ZIPALIGN}" -f 4 "${apkdir}/dist/${apkdir}.apk" "${apkdir}/dist/release_${apkdir}.apk" fi |
out.apk是jenkins打出的原始包 ,new_out.apk就是修改AndroidManiest.xml重新签名的灰度测试包。
IOS修改info.plist后重新打包 (Xcode9 环境下亲测)
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 |
#BUILD_XCODE_PROJECT unity导出的xcode工程 #BUILD_OUTPUT_IPA jenkins自动打包后,把ipa放在BUILD_XCODE_PROJECT目录下 #BUILD_MOBILE_PROVISION xxxxx.mobileprovision if [[ -f "${BUILD_OUTPUT_IPA}" ]]; then cd ${BUILD_XCODE_PROJECT} if [[ -d "Payload" ]]; then rm -rf "Payload" fi unzip ${BUILD_OUTPUT_IPA} cd Payload app="" for filename in `ls` do app=$filename done cd ${app} rm -rf _CodeSignature cp -rf "${BUILD_MOBILE_PROVISION}/xxxxx.mobileprovision" "embedded.mobileprovision" /usr/libexec/PlistBuddy -c "Set :gray.test debug" Info.plist /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.xxx.xxx" Info.plist cd ${BUILD_XCODE_PROJECT} entitlementsPlist="Entitlements.plist" rm -rf ${entitlementsPlist} echo '<?xml version="1.0" encoding="UTF-8"?>' >> ${entitlementsPlist} echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> ${entitlementsPlist} echo '<plist version="1.0">' >> ${entitlementsPlist} echo '<dict>' >> ${entitlementsPlist} echo '\t<key>application-identifier</key>' >> ${entitlementsPlist} echo '\t<string>XXXXXXXXXX.com.xxx.xxx</string>' >> ${entitlementsPlist} echo '\t<key>keychain-access-groups</key>' >> ${entitlementsPlist} echo '\t<array>' >> ${entitlementsPlist} echo '\t\t<string>XXXXXXXXXX.com.xxx.xxx</string>' >> ${entitlementsPlist} echo '\t</array>' >> ${entitlementsPlist} echo "</dict>" >> ${entitlementsPlist} echo "</plist>" >> ${entitlementsPlist} cat ${entitlementsPlist} codesign -f -s "iPhone Distribution: XXXXXXXXXX Online Tech Co., Ltd." --entitlements "${entitlementsPlist}" "Payload/${app}" outipa="new_$(basename $BUILD_OUTPUT_IPA .ipa).ipa" zip -qr "${outipa}" "Payload/" fi |
这里的例子是 把一个用个人证书签名的ipa重新签名成企业证书,重新签名后就可以装在任意手机上测试了。如果你想重新签名成个人证书,可以把对应证书的entitlements.plist找到,向上面这样赋值重新签名即可。
out.ipa是jenkins打出的原始包 ,new_out.ipa就是修改info.plist重新签名企业证书后的灰度测试包。
IOS我在多啰嗦一句,由于IOS最终发布给appstore必须用dist证书来打包,但是dist证书打包完以后我们无法在手机上查看效果。如果你对dist的包不放心的话可以也可以用上面的方法把它转成企业证书,这样就可以装在手机上看dist包的效果了。
- 本文固定链接: https://www.xuanyusong.com/archives/4448
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
不过这么麻烦,买个可以进行域名重定向的路由器,要测灰度时,连这个Wifi就行了.我 们都是这样搞的,不用重出包的.
我们也是这么做的
也可以用BundleID来判断是哪种包,codesign好像自带修改BundleID的功能?这样就省去修改plist的步骤
BundleID可以修改,不过游戏游戏功能会用这个BundleID 改了的话游戏功能可能就不对了。。