TargetRules 导入证书和 Provision

传统的打包 ios 时,需要手动在 Project Settings-Platforms-IOS 中选择打包要使用的 CertificateProvision,当需要切换打包 Configuration 的时候就需要打开编辑器重新选择一遍(因为 Development 和 Shipping 用到的证书不同),很麻烦,我是一个非常讨厌做重复操作的人,所以研究了一下解决了这个问题。
也是得益于 UE 本身提供了代码中导入 CertificateProvision的方式(之前我还写了自动化把证书导入到系统中,其实不用了)。
在前面的笔记中提到过 UE 的 Target 也提供了平台相关的 Target 对象:平台相关 Target,要实现本文提到的需求就要通过控制 IOSPlatform 来实现。

IOSPlatform提供了以下几个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// UnrealBuildTool/Platform/UEBuildIOS.cs

/// <summary>
/// Manual override for the provision to use. Should be a full path.
/// </summary>
[CommandLine("-ImportProvision=")]
public string ImportProvision = null;

/// <summary>
/// Imports the given certificate (inc private key) into a temporary keychain before signing.
/// </summary>
[CommandLine("-ImportCertificate=")]
public string ImportCertificate = null;

/// <summary>
/// Password for the imported certificate
/// </summary>
[CommandLine("-ImportCertificatePassword=")]
public string ImportCertificatePassword = null;

通过操作它们的值来实现自动化导入证书和 Provision,我写了一段使用代码:

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
46
47
48
49
50
51
52
public class FGameTarget : TargetRules
{
public FGameTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.V1;
ExtraModuleNames.AddRange(new string[] { "FGame" } );

// for package dSYM
bDisableDebugInfo = true;
if(Target.Platform == UnrealTargetPlatform.IOS)
{
DirectoryReference ProjectDir = ProjectFile.Directory;
IOSPlatform.bGeneratedSYM = true;
string PackageConfiguration = "";

// import cer/provision
switch (Target.Configuration)
{
case UnrealTargetConfiguration.Debug:
case UnrealTargetConfiguration.Development:
case UnrealTargetConfiguration.Test:
{
PackageConfiguration = "Development";
IOSPlatform.bForDistribution = false;
break;
};
case UnrealTargetConfiguration.Shipping:
{
PackageConfiguration = "Distibution";
IOSPlatform.bForDistribution = true;
break;
};
}

string cerPath = Path.Combine(ProjectDir.FullName, "Source/ThirdParty/iOS/",PackageConfiguration,"XXXXXX_IOS.p12");
string proversionPath = Path.Combine(ProjectDir.FullName, "Source/ThirdParty/iOS/",PackageConfiguration,"com.tencent.xxxx.xx_SignProvision.mobileprovision");
string cerPassword = "password";

Console.WriteLine("Import Certificate:"+cerPath);
Console.WriteLine("Import Provision:"+proversionPath);

if (File.Exists(cerPath) && File.Exists(proversionPath))
{
Console.WriteLine("Import Certificate & Provision set to IOSPlatform");
IOSPlatform.ImportCertificate = cerPath;
IOSPlatform.ImportProvision = proversionPath;
IOSPlatform.ImportCertificatePassword = cerPassword;
}
}
}
}

在打包 IOS 时就会自动使用所指定的证书了,并且会在 Shipping 时自动化启用 Distribution,这样就可以避免要事先把证书和provision 导入到系统中。