Unity2019.3 持续集成 通过xcodebuild打包ipa踩坑

最近接手了持续集成工作,对unity项目(2019.3+)进行自动打包
略过搭建jenkins的过程直接进入重点大坑

前提:使用unity与xcode通过GUI打包ipa成功。

参考教程-打包命令与参数讲解

坑点:使用xcodebuild打包ipa报错

2019.3之后的unity版本生成xcode工程时会生成一个UnityFramework的target。
按照上文提到的自动打包命令执行,xcodebuild archive执行完成后,xcodebuild export会报错。

xcodebuild  -exportArchive -archivePath build/Unity-iPhone-adhoc.xcarchive -exportOptionsPlist ./ExportOptions.plist -exportPath ipa/VillageAdHoc
2020-07-05 15:29:59.613 xcodebuild[14686:230312] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/qh/zt1y2t1136z5nb6263m318980000gn/T/Unity-iPhone_2020-07-05_15-29-59.612.xcdistributionlogs'.
error: exportArchive: UnityFramework.framework does not support provisioning profiles.

Error Domain=IDEProvisioningErrorDomain Code=10 "UnityFramework.framework does not support provisioning profiles." UserInfo={IDEDistributionIssueSeverity=3, NSLocalizedDescription=UnityFramework.framework does not support provisioning profiles., NSLocalizedRecoverySuggestion=UnityFramework.framework does not support provisioning profiles, but provisioning profile VillageAdHoc has been manually specified. Remove this item from the "provisioningProfiles" dictionary in your Export Options property list.}

** EXPORT FAILED **

出现这个错误的原因是,自动签名了UnityFramework,而UnityFramework不需要任何的签名,所以出现了该错误。
但是实际测试时出现了奇怪的情况:执行xcodebuild archive成功后,导入.xcarchive,并在xcode进行export操作是成功的,但是执行xcodebuild export时报错!

解决办法

在unity中编辑BuildProcessor.cs
#if UNITY_IOS
using UnityEditor.iOS.Xcode;
#endif
public class BuildProcessor : IPreprocessBuildWithReport, IPostprocessBuildWithReport{
	public void OnPostprocessBuild(BuildReport report)
	{
	    #if UNITY_IOS
	        if (report.summary.platform != BuildTarget.iOS)
	            return;
	        // 配置文件路径
	        string projectPath = report.summary.outputPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
	        // 实例化工具类
	        PBXProject pbxProject = new PBXProject();
	        // 读取当前配置
	        pbxProject.ReadFromFile(projectPath);
	        // 关闭 UnityFramework 中的 bitcode
	        string framework = pbxProject.TargetGuidByName("UnityFramework");            
	        pbxProject.SetBuildProperty(framework, "ENABLE_BITCODE", "NO");
	        pbxProject.SetBuildProperty(framework, "CODE_SIGN_STYLE", "Manual");
	        pbxProject.SetBuildProperty(framework, "SUPPORTS_MACCATALYST", "NO");
	        
	        // 按环境设置项目配置中的 CODE_SIGN_IDENTITY
	        string unityIphone = pbxProject.GetUnityMainTargetGuid();
	        // 如果环境是debug 则传入 iPhone Developer
	        // pbxProject.SetBuildProperty(unityIphone, "CODE_SIGN_IDENTITY", "iPhone Developer");
	        // 否则传入 iPhone Distribution
	        pbxProject.SetBuildProperty(unityIphone, "CODE_SIGN_IDENTITY", "iPhone Distribution");
	        pbxProject.SetBuildProperty(unityIphone, "DEVELOPMENT_TEAM", "your team id");
	        pbxProject.SetBuildProperty(unityIphone, "PROVISIONING_PROFILE_SPECIFIER", "your profile name");
	        pbxProject.SetBuildProperty(unityIphone, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Distribution");
	        // 写入配置文件
	        pbxProject.WriteToFile (projectPath);
	    #endif
	}
}

这段代码是在unity导出xcode工程之后,自动执行的方法。用来自动设置xcode工程的配置。这里做的修改也可以用shell或者其他语言实现,最终修改目标的是xcode项目中的Unity-iPhone.xcodeproj包中的project.pbxproj配置文件。
需要修改的设置项目为:

// UnityFramework
{
	// 关闭UnityFramework的bitcode
	"ENABLE_BITCODE": "NO"
	// 设置UnityFramework的签名方式为手动签名
	"CODE_SIGN_STYLE": "Manual"
	// 关闭mac平台的支持(默认为YES, 如需要支持mac平台则不设置这一项即可)
	"SUPPORTS_MACCATALYST": "NO"
}

// Unity-iPhone
{
	// 根据环境传入 iPhone Developer 或 iPhone Distribution
	// 这里根据xcode GUI手动打包时的profile进行设置,如果本设置与profile不一致,则会出现签名错误的问题
	"CODE_SIGN_IDENTITY": "iPhone Distribution"
	// 设置所有sdk的环境,一般与CODE_SIGN_IDENTITY一致
	"CODE_SIGN_IDENTITY[sdk=iphoneos*]": "iPhone Distribution"
	// 传入签名证书的团队id
	"DEVELOPMENT_TEAM": "your team id"
	// 使用的profile名称
	"PROVISIONING_PROFILE_SPECIFIER": "your profile name"
}

这样就可以通过unity生成设置好的xcode项目了。

通过xcodebuild进行archive操作
xcode_proj_path="unity导出的xcode项目路径"
configuration="Release"
xcodebuild -scheme Unity-iPhone -configuration $configuration -archivePath "${xcode_proj_path}/build/Unity-iPhone-adhoc.xcarchive" clean archive build -project "${xcode_proj_path}/Unity-iPhone.xcodeproj"
重要的事情说三遍
注意:不要添加CODE_SIGN_IDENTITYPROVISIONING_PROFILE_SPECIFIER这两个参数
注意:不要添加CODE_SIGN_IDENTITYPROVISIONING_PROFILE_SPECIFIER这两个参数
注意:不要添加CODE_SIGN_IDENTITYPROVISIONING_PROFILE_SPECIFIER这两个参数

因为这两个参数对Unity-iPhone和UnityFramework需要分别配置,而且在上文c#中已经配置过了。
执行sh,经过漫长的编译后,如果执行成功的话,你会看到(通常有很多日志,你只能看到最后一条):

** CLEAN SUCCEEDED **
** ARCHIVE SUCCEEDED **
** BUILD SUCCEEDED **

分别对应sh中的clean archive build
这时在xcode项目目录中会生成./build/Unity-iPhone-adhoc.xcarchivexcode归档文件

通过xcodebuild进行export操作
xcode_proj_path="unity导出的xcode项目路径"
plist_path="通过xcode GUI手动导出ipa时, 生成的ExportOptions.plist文件的存放路径"
xcodebuild -exportArchive -archivePath "${xcode_proj_path}/build/Unity-iPhone-adhoc.xcarchive" -exportOptionsPlist $plist_path -exportPath "${xcode_proj_path}/ipa"

执行sh,如果看到

** EXPORT SUCCEEDED **

那么,恭喜你,ipa包已经生成成功了。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐