Включить возможности для Unity3D xCode Project в пост-процессе
У меня есть проект Unity3D для iOS, в котором я использую Game Center и покупки в приложении (через сторонние плагины), но когда я собираю проект Unity3D в xCode, в разделе "Возможности" Game Center и покупки в приложении отключаются. Мне нужно включить их в методе PostProcessBuild. Я пытался использовать xCodeApi через этот код:
string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
PBXProject proj = new PBXProject();
proj.ReadFromString(File.ReadAllText(projPath));
string target = proj.TargetGuidByName("Unity-iPhone");
proj.AddCapability (target, PBXCapabilityType.GameCenter);
proj.AddCapability (target, PBXCapabilityType.InAppPurchase);
File.WriteAllText(projPath, proj.ToString());
Но после этого xCode не может открыть созданный проект (он просто срывается). Как добавить эти две возможности, не устанавливая их вручную в xCode?
4 ответа
Таким образом, проблема была с неверным projPath и что я не включил iCloud. Этот код работает:
[PostProcessBuild(999)]
public static void AddCapabilities(BuildTarget buildTarget, string pathToBuiltProject)
{
if (buildTarget == BuildTarget.iOS) {
string projPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject proj = new PBXProject ();
proj.ReadFromString (File.ReadAllText (projPath));
string target = proj.TargetGuidByName ("Unity-iPhone");
proj.AddCapability (target, PBXCapabilityType.iCloud);
proj.AddCapability (target, PBXCapabilityType.GameCenter);
proj.AddCapability (target, PBXCapabilityType.InAppPurchase);
File.WriteAllText (projPath, proj.WriteToString ());
}
}
На данный момент у меня проблемы только с установкой хранилища значений ключей флагов iCloud и CloudKit в true. Насколько я прочитал, ему нужен какой-то файл прав, который я не знаю, где найти. Если вы знаете, как помочь, я был бы признателен за некоторые комментарии.
Вот новый способ, которым это достижимо:
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.iOS.Xcode;
public class CapabilityPostprocessBuild : IPostprocessBuildWithReport
{
public int callbackOrder => 999;
public void OnPostprocessBuild(BuildReport report)
{
OnPostprocessBuild(report.summary.platform, report.summary.outputPath);
}
public void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
string projPath = PBXProject.GetPBXProjectPath(path);
PBXProject proj = new PBXProject();
proj.ReadFromFile(projPath);
ProjectCapabilityManager manager = new ProjectCapabilityManager(
projPath,
"Entitlements.entitlements",
targetGuid: proj.GetUnityMainTargetGuid()
);
manager.AddiCloud(true, false, null);
manager.WriteToFile();
}
}
}
Ты можешь использовать ProjectCapabilityManager
добавить iCloud
возможность с key-value
флаг хранения
using XcodeUnityCapability = UnityEditor.iOS.XcodeUnity.ProjectCapabilityManager;
public class IosPostProcessBuild : MonoBehaviour
{
[PostProcessBuild]
private static void PostBuildActions(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
XcodeUnityCapability projCapability = new XcodeUnityCapability(projPath, "Unity-iPhone/mmk.entitlements", "Unity-iPhone");
projCapability.AddGameCenter();
string[] empty = null;
projCapability.AddiCloud(true, false, empty);
projCapability.WriteToFile();
}
}
}
XcodeUnity
переименован в пространство имен, вы можете взять xcode api отсюда https://bitbucket.org/Unity-Technologies/xcodeapi/src
По состоянию на 21.11.23 правильно отмеченный здесь ответ устарел. Unity как обычно сломала собственный API. Например, для Game Center (фреймворка GameKit) будет работать следующее:
[PostProcessBuild]
public static void ProcessForiOS(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
// Add Game Center capability. Required since Unity and Apple ****** everything up with Xcode 15.
string projectPath = PBXProject.GetPBXProjectPath(path);
PBXProject project = new PBXProject();
project.ReadFromString(File.ReadAllText(projectPath));
string targetGuid = project.GetUnityMainTargetGuid();
project.AddFrameworkToProject(targetGuid, "GameKit.framework", false);
File.WriteAllText(projectPath, project.WriteToString());
}
}