0%

使用 Unity 2020 版本导出 Xcode 工程

公司的项目使用的是 Unity 2018 版本和魔改后的 XUPorter 导出的,后面需要升级到 Unity 2020 版本。但是 Unity 从 2019.3 版本后导出 Xcode 工程相比之前的版本有所修改,这里记录了升级过程中遇到的坑。

工程设置

  • iOS 最低版本:Unity 2020 是 11.0。Unity 2018 是 9.0

编译错误,提示 PBXProject.GetUnityTargetName() 方法被废弃

  • Unity 的 Xcode 工程会存在两个 target。根据选择的 target,将旧代码
1
2
// Unity 2018
string targetGuid = xcodeProj.TargetGuidByName(PBXProject.GetUnityTargetName())

改为

1
2
3
4
// Unity 2020
string targetGuid = xcodeProj.GetUnityMainTargetGuid(); // 获取 Unity-iPhone 的 target
// 或者
string targetGuid = xcodeProj.GetUnityFrameworkTargetGuid(); // 获取 UnityFramework 的 target

导出工程报错,提示 Exception: A required capability description is not set.

完整提示如下:

1
2
3
4
WebCamTexture class is used but Camera Usage Description is empty. App will not work on iOS 10+.
LocationService class is used but Locations Usage Description is empty. App will not work on iOS 10+.
Microphone class is used but Microphone Usage Description is empty. App will not work on iOS 10+.
Exception: A required capability description is not set.

PlayerSettings 下 iOS 中的 Camera Usage DescriptionLocations Usage DescriptionMicrophone Usage Description 这几个选项必须有值。

修改 PlayerSettings 或者使用代码设置:

1
2
3
PlayerSettings.iOS.cameraUsageDescription = "use camera"; // 相机使用描述,修改为相应的文案,下同
PlayerSettings.iOS.locationUsageDescription = "use location"; // 位置使用描述
PlayerSettings.iOS.microphoneUsageDescription = "use microphone"; // 麦克风使用描述

导出工程报错,提示 Exception: The given path BuglyMod/BuglyBridge.h does not refer to a file in a known build section

  • Unity 2018 的代码只需要使用 AddFileToBuild 接口就可以添加文件,自动识别添加的是源文件、库文件或者资源文件。
1
2
string fileGuid = xcodeProj.AddFile(destPath, destPath, PBXSourceTree.Source); // 将文件添加到工程中,获取文件的 GUID
xcodeProj.AddFileToBuild(targetName, fileGuid); // 将文件加入编译
  • Unity 2020 添加有些文件时需要指定 build section 才能添加成功。
1
2
3
var fileGuid = xcodeProj.AddFile(destPath, destPath, PBXSourceTree.Source); // 将文件添加到工程中,获取文件的 GUID
var sourcesBuildPhase = xcodeProj.GetSourcesBuildPhaseByTarget(unityFrameworkTargetGuid); // 获取 Compile Sources 的 Build Phase,可以在 Xcode 工程中看到
xcodeProj.AddFileToBuildSection(unityFrameworkTargetGuid, sourcesBuildPhase, fileGuid); // 加入文件
  • 具体的代码在 XcodePostProcess.cs 可以看到。

添加文件时的 target 选择

  • Unity 2020 生成的 Xcode 工程有两个 target,一个是 Unity-iPhone,一个是 UnityFramework。获取方式分别为:
1
2
string unityMainTargetGuid = xcodeProj.GetUnityMainTargetGuid(); // Unity-iPhone
string unityFrameworkTargetGuid = xcodeProj.GetUnityFrameworkTargetGuid(); // UnityFramework

源文件

  • .h .m .mm .c .cpp 等源文件,target 选择 UnityFramework,BuildPhase 选择 SourcesBuildPhase
1
2
3
var fileGuid = xcodeProj.AddFile(destPath, destPath, PBXSourceTree.Source); // 将文件添加到工程中,获取文件的 GUID
var sourcesBuildPhase = xcodeProj.GetSourcesBuildPhaseByTarget(unityFrameworkTargetGuid); // 获取 Compile Sources 的 Build Phase,可以在 Xcode 工程中看到
xcodeProj.AddFileToBuildSection(unityFrameworkTargetGuid, sourcesBuildPhase, fileGuid); // 加入文件

库文件

  • .framework 文件,target 选择 UnityFramework,可以不用指定 BuildPhase。
  • .a 文明考吗。target 下面则 UnityFramework,BuildPhase 选择 FrameworksBuildPhase
1
2
3
var fileGuid = xcodeProj.AddFile(destPath, destPath, PBXSourceTree.Source);
var frameworksBuildPhase = xcodeProj.GetFrameworksBuildPhaseByTarget(unityFrameworkTargetGuid); // 获取 Link Binary With Libraries 的 Build Phase,可以在 Xcode 工程中看到
xcodeProj.AddFileToBuildSection(unityFrameworkTargetGuid, frameworksBuildPhase, fileGuid);

embed framework 文件

  • target 选择 Unity-iPhone。例如 AliyunNlsSdk.framework

资源文件

  • .json .plist .bundle .config 等资源文件,target 选择 Unity-iPhone,BuildPhase 选择 ResourcesBuildPhase
1
2
3
var fileGuid = xcodeProj.AddFile(destPath, destPath, PBXSourceTree.Source);
var resourceBuildPhase = xcodeProj.GetResourcesBuildPhaseByTarget(unityMainTargetGuid); // 获取 Copy Bundle Resources 的 Build Phase,可以在 Xcode 工程中看到
xcodeProj.AddFileToBuildSection(unityMainTargetGuid, resourceBuildPhase, fileGuid);

xcodebuild archive 报错,提示 error: UnityFramework does not support provisioning profiles.

修改指定参数

PRODUCT_NAME -> PRODUCT_NAME_APP

PROVISIONING_PROFILE -> PROVISIONING_PROFILE_APP

PROVISIONING_PROFILE_SPECIFIER -> PROVISIONING_PROFILE_SPECIFIER_APP

OTHER_LDFLAGS -> OTHER_LDFLAGS_FRAMEWORK

将旧的脚本

1
2
3
4
5
6
7
8
# 旧脚本
xcodebuild archive -project Unity-iPhone.xcodeproj -scheme Unity-iPhone -archivePath Unity-iPhone.xcarchive -configuration Release \
CODE_SIGN_STYLE="Manual" \
PROVISIONING_STYLE="Manual" \
CODE_SIGN_IDENTITY="Apple Development" \
PROVISIONING_PROFILE="provision uuid" \
DEVELOPMENT_TEAM="teamid" \
PRODUCT_BUNDLE_IDENTIFIER="bundle id"

修改为

1
2
3
4
5
6
7
8
# 修改后的脚本
xcodebuild archive -project Unity-iPhone.xcodeproj -scheme Unity-iPhone -archivePath Unity-iPhone.xcarchive -configuration Release \
CODE_SIGN_STYLE="Manual" \
PROVISIONING_STYLE="Manual" \
CODE_SIGN_IDENTITY="Apple Development" \
PROVISIONING_PROFILE_APP="provision uuid" \ # 修改这里
DEVELOPMENT_TEAM="teamid" \
PRODUCT_BUNDLE_IDENTIFIER_APP="bundle id" # 修改这里

参考链接