2023-04-21 23:10:01 +08:00

349 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if UNITY_EDITOR_OSX
using UnityEngine;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEditor.iOS.Xcode;
using System.IO;
#endif
namespace BFEditor.Build
{
public static class BuildIOSUtils
{
#if UNITY_EDITOR_OSX
const string IOS_DEFINE_SYMBOLS = "THREAD_SAFE;USE_AB";
const string DEV_XCODE_LOCAL_PATH = "BFVersions/ios/dev";
const string RELEASE_XCODE_LOCAL_PATH = "BFVersions/ios/release";
static string devXCodePath = Application.dataPath + "/../" + DEV_XCODE_LOCAL_PATH;
static string releaseXCodePath = Application.dataPath + "/../" + RELEASE_XCODE_LOCAL_PATH;
static string devOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/dev/ExportOptions.plist";
static string releaseOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/release/ExportOptions.plist";
static string publishOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/dis/ExportOptions.plist";
public static bool BuildIOSPlayer(BuildInfo buildInfo)
{
var buildTarget = BuildTarget.iOS;
// 检查平台
if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
{
Debug.LogError("[bferror]当前没有在对应平台");
return false;
}
// 重新生成XLua
CompileScriptsUtils.RegenerateXLuaCode(true);
// 打包设置
BuildSettings(buildInfo);
// 开始打包
var bpOptions = GetBuildOptions(buildInfo);
var report = BuildPipeline.BuildPlayer(bpOptions);
if (report.summary.result == BuildResult.Succeeded)
{
return BuildIpaFromXCode(buildInfo);
}
else
{
Debug.LogError("[bferror]unity打包xcode失败");
return false;
}
}
/// <summary>
/// 打包设置
/// </summary>
static void BuildSettings(BuildInfo buildInfo)
{
// 设置bundleVersion
PlayerSettings.bundleVersion = buildInfo.version;
// 设置buildNumber
PlayerSettings.iOS.buildNumber = buildInfo.version_code.ToString();
// 设置竖屏
PlayerSettings.defaultInterfaceOrientation = UIOrientation.Portrait;
PlayerSettings.allowedAutorotateToPortrait = false;
PlayerSettings.allowedAutorotateToPortraitUpsideDown = false;
PlayerSettings.allowedAutorotateToLandscapeLeft = false;
PlayerSettings.allowedAutorotateToLandscapeRight = false;
// 允许Xcode根据appleDeveloperTeamID自动签署应用程序
PlayerSettings.iOS.appleEnableAutomaticSigning = !buildInfo.IsPublish();
// 使用手动签名时iOS资源调配配置文件的类型自动
PlayerSettings.iOS.iOSManualProvisioningProfileType = buildInfo.IsPublish() ? ProvisioningProfileType.Distribution : ProvisioningProfileType.Automatic;
// 关闭启动动画
PlayerSettings.SplashScreen.show = false;
// 设置包名
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.iOS, buildInfo.bundleName);
Debug.Log("[bfinfo]设置包名:" + buildInfo.bundleName);
// 是否跳过版本控制
var symbols = IOS_DEFINE_SYMBOLS;
if (buildInfo.skipVersion)
{
symbols = symbols + ";SKIP_VERSION;";
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS, symbols);
Debug.Log("[bfinfo]设置defineSymbols: " + symbols);
// 是否是dev
var development = buildInfo.IsDevChannel();
EditorUserBuildSettings.development = development;
// 商品名称
if (buildInfo.IsPublish())
{
PlayerSettings.productName = "Heroic Expedition";
}
else
{
PlayerSettings.productName = development ? "b6-dev" : "b6-release";
}
// BuildType设置dev/release
EditorUserBuildSettings.iOSBuildConfigType = development ? iOSBuildType.Debug : iOSBuildType.Release;
// 使用IL2CPP
var scriptImp = ScriptingImplementation.IL2CPP;
PlayerSettings.SetScriptingBackend(BuildTargetGroup.iOS, scriptImp);
// 目标平台架构目前支持ARM64
PlayerSettings.SetArchitecture(BuildTargetGroup.iOS, 1);
}
/// <summary>
/// 获取打包参数
/// </summary>
static BuildPlayerOptions GetBuildOptions(BuildInfo buildInfo)
{
var bpOptions = new BuildPlayerOptions();
bpOptions.scenes = AssetBundleUtils.GetBuildScenes();
bpOptions.target = BuildTarget.iOS;
var path = buildInfo.IsReleaseChannel() ? RELEASE_XCODE_LOCAL_PATH : DEV_XCODE_LOCAL_PATH;
bpOptions.locationPathName = path;
Debug.Log("[bfinfo]xcode path : " + path);
var absolutePath = buildInfo.IsReleaseChannel() ? releaseXCodePath : devXCodePath;
if (Directory.Exists(absolutePath))
{
Directory.Delete(absolutePath, true);
}
if (!buildInfo.IsPublish())
{
var options = BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging;
bpOptions.options = options;
}
return bpOptions;
}
/// <summary>
/// 打包ipa
/// </summary>
static bool BuildIpaFromXCode(BuildInfo buildInfo)
{
// 修改XCode设置
FixXCodeProject(buildInfo);
// 权限
UnlockKeyChain();
// archive
if (!Archive(buildInfo))
{
return false;
}
// 导出ipa
if (!ExportIpa(buildInfo))
{
return false;
}
return true;
}
/// <summary>
/// xCode工程设置
/// </summary>
static void FixXCodeProject(BuildInfo buildInfo)
{
var isDev = buildInfo.IsDevChannel();
var xCodeProjectPath = isDev ? devXCodePath : releaseXCodePath;
var path = xCodeProjectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
var pbxProject = new PBXProject();
pbxProject.ReadFromFile(path);
var targetGuid = pbxProject.TargetGuidByName("Unity-iPhone");
pbxProject.AddBuildProperty(targetGuid, "OTHER_LDFLAGS", "-ObjC");
pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
pbxProject.SetBuildProperty(targetGuid, "DEVELOPMENT_TEAM", "49QQW8856Q");
if (buildInfo.IsPublish())
{
pbxProject.SetBuildProperty(targetGuid, "PROVISIONING_PROFILE_SPECIFIER", "ub_appstore_dis");
}
// 添加系统库
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libsqlite3.tbd");
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libz.1.tbd");
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libiconv.2.tbd");
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libresolv.9.tbd");
var pListPath = Path.Combine(xCodeProjectPath, "Info.plist");
var pList = new PlistDocument();
pList.ReadFromFile(pListPath);
// 版本号
var vKey = "CFBundleShortVersionString";
var vValue = new PlistElementString(buildInfo.version);
var pListRoot = pList.root;
var rootDict = pListRoot.values;
if (!rootDict.ContainsKey(vKey))
{
rootDict.Add(vKey, vValue);
}
else
{
rootDict[vKey] = vValue;
}
// VersionCode
var vCodeKey = "CFBundleVersion";
var vCodeValue = new PlistElementString(buildInfo.version_code.ToString());
if (!rootDict.ContainsKey(vCodeKey))
{
rootDict.Add(vCodeKey, vCodeValue);
}
else
{
rootDict[vCodeKey] = vCodeValue;
}
// 数美SDK会使用位置必须加入这个说明
var localtionKey = "NSLocationWhenInUseUsageDescription";
var localtionValue = new PlistElementString("We use your location to give you a better localization.");
if (!rootDict.ContainsKey(localtionKey))
{
rootDict.Add(localtionKey, localtionValue);
}
else
{
rootDict[localtionKey] = localtionValue;
}
// 提审提示缺少出口合规证明,这里直接设置为false即可
var encryptionKey = "ITSAppUsesNonExemptEncryption";
var encryptionValue = new PlistElementBoolean(false);
if (!rootDict.ContainsKey(encryptionKey))
{
rootDict.Add(encryptionKey, encryptionValue);
}
else
{
rootDict[encryptionKey] = encryptionValue;
}
pList.WriteToFile(pListPath);
pbxProject.WriteToFile(path);
}
//添加系统lib方法
static void AddSystemLibReferenceToProject(PBXProject pbxProject, string targetGuid, string lib)
{
var fileGuid = pbxProject.AddFile("usr/lib/" + lib, "Frameworks/" + lib, PBXSourceTree.Sdk);
pbxProject.AddFileToBuild(targetGuid, fileGuid);
}
/// <summary>
/// Archive
/// </summary>
static bool Archive(BuildInfo buildInfo)
{
Debug.Log("[bfinfo]正在archive...");
var result = true;
var xCodeProjectPath = buildInfo.IsDevChannel() ? devXCodePath : releaseXCodePath;
var archivePath = xCodeProjectPath + "/build/archive/Unity-iPhone.xcarchive";
var args = string.Format("archive -scheme Unity-iPhone -configuration Release -archivePath {0}", archivePath);
BFEditorUtils.RunCommond("xcodebuild", args, xCodeProjectPath,
(info) =>
{
Debug.Log(info);
},
(error) =>
{
if (error.Contains("ARCHIVE FAILED")) // 失败标志
{
result = false;
}
Debug.LogError("[bferror] " + error);
}
);
return result;
}
/// <summary>
/// 导出ipa
/// </summary>
static bool ExportIpa(BuildInfo buildInfo)
{
Debug.Log("[bfinfo]正在导出ipa...");
var result = false;
var xCodeProjectPath = buildInfo.IsDevChannel() ? devXCodePath : releaseXCodePath;
string exportPListPath;
if (buildInfo.IsPublish())
{
exportPListPath = publishOptionsPListPath;
}
else
{
exportPListPath = buildInfo.IsDevChannel() ? devOptionsPListPath : releaseOptionsPListPath;
}
var ipaPath = xCodeProjectPath + "/build/ipa";
var archivePath = xCodeProjectPath + "/build/archive/Unity-iPhone.xcarchive";
var args = string.Format("-exportArchive -archivePath {0} -exportPath {1} -exportOptionsPlist {2} -allowProvisioningUpdates", archivePath, ipaPath, exportPListPath);
BFEditorUtils.RunCommond("xcodebuild", args, null,
(info) =>
{
if(info.Contains("EXPORT SUCCEEDED"))
{
result = true;
}
},
(error) =>
{
}
);
return result;
}
/// <summary>
/// 远程打包签名ipa时需要钥匙串权限
/// </summary>
static void UnlockKeyChain()
{
BFEditorUtils.RunCommond("security", "-v unlock-keychain -p '123456' /Users/aoddabao/Library/Keychains/login.keychain-db", null,
(msg) =>
{
Debug.Log(msg);
},
(msg) =>
{
Debug.LogError(msg);
}
);
}
#endif
}
}