首页 >Unity3D频道 >【Unity3D研究院之游戏开发】 > Unity3D研究院之生成客户端灰度测试包(九十四)
2018
01-26

Unity3D研究院之生成客户端灰度测试包(九十四)

灰度测试包应该和正式包的内容完全一致,只是添加了一些辅助的开关,例如:可以进调试服务器、可以输入gm指令、可以下载测试url的cdn热更资源。如果开发都打两个包的话就很麻烦。日后游戏上线后我们需要,dsym和带符号表的so用来还原闪退的堆栈。Android只是编译unity的时候会生成il2cpp.so.debug,iOS则每次编译Xcode会生成。所以理想化的灰度测试包和正式测试包,最好可以共享一份符号表的so和dsym,或者灰度测试包和正式包是同一个包。

目前有2个方案(如果有更好的方案欢迎大家在下面补充)

1.判断网络状态,如果连接了特定的网络,例如公司的wifi,就是灰度测试包,没连公司网络则属于正式包。

获取wifi名

Android Java代码

	/**
	 * 获取连接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代码

     /**
     * 获取连接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中添加一行

        <!--灰度测试标识-->
        <meta-data android:name="gray.test" android:value="release" />
        <!--灰度测试标识-->

ios info.plist中加一行

    <key>gray.test</key>
    <string>release</string>

灰度测试包就是把ipa和apk里面的这个值改了重新打包,程序中代码会去取这个值来做逻辑判断是否灰度测试包。

Android修改AndroidManiest.xml后重新打包

#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重新签名的灰度测试包。

Snip20180126_10

IOS修改info.plist后重新打包  (Xcode9 环境下亲测)

#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 'tt<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重新签名企业证书后的灰度测试包。

Snip20180126_9

IOS我在多啰嗦一句,由于IOS最终发布给appstore必须用dist证书来打包,但是dist证书打包完以后我们无法在手机上查看效果。如果你对dist的包不放心的话可以也可以用上面的方法把它转成企业证书,这样就可以装在手机上看dist包的效果了。

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之生成客户端灰度测试包(九十四)》有 4 条评论

  1. 老刘说:

    不过这么麻烦,买个可以进行域名重定向的路由器,要测灰度时,连这个Wifi就行了.我 们都是这样搞的,不用重出包的.

  2. rainssong说:

    也可以用BundleID来判断是哪种包,codesign好像自带修改BundleID的功能?这样就省去修改plist的步骤

留下一个回复

你的email不会被公开。 必填项已用 * 标注。