在后处理中启用 Unity3D xCode 项目的功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44311313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:00:12  来源:igfitidea点击:

Enable capabilities for Unity3D xCode Project in postprocess

iosxcodeunity3dpost-processing

提问by Sam Stone

I have a Unity3D iOS project, where I use Game Center and In-App Purchases(via third-party plugins), but when I build Unity3D project into xCode, in the Capabilities section Game Center and In-App Purchases are disabled. I need to enable them in a PostProcessBuild method. I tried using xCodeApi via this code:

我有一个 Unity3D iOS 项目,我在其中使用游戏中心和应用内购买(通过第三方插件),但是当我将 Unity3D 项目构建到 xCode 中时,在功能部分中,游戏中心和应用内购买被禁用。我需要在 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());

But after this xCode is unable to open the created project(it just crashes immidietly). How do I add these two capabilities without setting them manually in xCode?

但是在此之后 xCode 无法打开创建的项目(它只是立即崩溃)。如何添加这两个功能而不在 xCode 中手动设置它们?

回答by Sam Stone

So the problem was with invalid projPath and that I did not enable iCloud. This code works:

所以问题在于无效的 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 ());

  }
}

For now I am having trouble only with setting iCloud flags key-value storage and CloudKit to true. As far as I've read, it needs some entitlement file, which I do not know where to find. If you know how to help, I would appreciate some comments.

现在我只在将 iCloud 标志键值存储和 CloudKit 设置为 true 时遇到问题。据我所知,它需要一些权利文件,我不知道在哪里可以找到。如果您知道如何提供帮助,我将不胜感激。

回答by Степан Проломов

you can use ProjectCapabilityManagerto add iCloudcapability with key-valuestorage flag

您可以使用存储标志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();
        }
    }
}

XcodeUnityis renamed namespace, you can take xcode api from here https://bitbucket.org/Unity-Technologies/xcodeapi/src

XcodeUnity重命名命名空间,您可以从这里获取 xcode api https://bitbucket.org/Unity-Technologies/xcodeapi/src

回答by Iggy

Here's a new way that this is achievable:

这是一种可以实现的新方法:

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();
        }
    }
}