349 lines
11 KiB
C#
349 lines
11 KiB
C#
#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 ? "b5-dev" : "b5-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
|
||
}
|
||
}
|