ProjectCapabilityManagerExtension.cs 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #if UNITY_IOS || UNITY_TVOS
  2. using System;
  3. using System.Reflection;
  4. using UnityEditor.iOS.Xcode;
  5. namespace AppleAuth.Editor
  6. {
  7. public static class ProjectCapabilityManagerExtension
  8. {
  9. private const string EntitlementsArrayKey = "com.apple.developer.applesignin";
  10. private const string DefaultAccessLevel = "Default";
  11. private const string AuthenticationServicesFramework = "AuthenticationServices.framework";
  12. private const BindingFlags NonPublicInstanceBinding = BindingFlags.NonPublic | BindingFlags.Instance;
  13. /// <summary>
  14. /// Extension method for ProjectCapabilityManager to add the Sign In With Apple capability in compatibility mode.
  15. /// In particular, adds the AuthenticationServices.framework as an Optional framework, preventing crashes in
  16. /// iOS versions previous to 13.0
  17. /// </summary>
  18. /// <param name="manager">The manager for the main target to use when adding the Sign In With Apple capability.</param>
  19. /// <param name="unityFrameworkTargetGuid">The GUID for the UnityFramework target. If null, it will use the main target GUID.</param>
  20. public static void AddSignInWithAppleWithCompatibility(this ProjectCapabilityManager manager, string unityFrameworkTargetGuid = null)
  21. {
  22. var managerType = typeof(ProjectCapabilityManager);
  23. var capabilityTypeType = typeof(PBXCapabilityType);
  24. var projectField = managerType.GetField("project", NonPublicInstanceBinding);
  25. var targetGuidField = managerType.GetField("m_TargetGuid", NonPublicInstanceBinding);
  26. var entitlementFilePathField = managerType.GetField("m_EntitlementFilePath", NonPublicInstanceBinding);
  27. var getOrCreateEntitlementDocMethod = managerType.GetMethod("GetOrCreateEntitlementDoc", NonPublicInstanceBinding);
  28. var constructorInfo = capabilityTypeType.GetConstructor(
  29. NonPublicInstanceBinding,
  30. null,
  31. new[] {typeof(string), typeof(bool), typeof(string), typeof(bool)},
  32. null);
  33. if (projectField == null || targetGuidField == null || entitlementFilePathField == null ||
  34. getOrCreateEntitlementDocMethod == null || constructorInfo == null)
  35. throw new Exception("Can't Add Sign In With Apple programatically in this Unity version");
  36. var entitlementFilePath = entitlementFilePathField.GetValue(manager) as string;
  37. var entitlementDoc = getOrCreateEntitlementDocMethod.Invoke(manager, new object[] { }) as PlistDocument;
  38. if (entitlementDoc != null)
  39. {
  40. var plistArray = new PlistElementArray();
  41. plistArray.AddString(DefaultAccessLevel);
  42. entitlementDoc.root[EntitlementsArrayKey] = plistArray;
  43. }
  44. var project = projectField.GetValue(manager) as PBXProject;
  45. if (project != null)
  46. {
  47. var mainTargetGuid = targetGuidField.GetValue(manager) as string;
  48. var capabilityType = constructorInfo.Invoke(new object[] { "com.apple.developer.applesignin.custom", true, string.Empty, true }) as PBXCapabilityType;
  49. var targetGuidToAddFramework = unityFrameworkTargetGuid;
  50. if (targetGuidToAddFramework == null)
  51. {
  52. targetGuidToAddFramework = mainTargetGuid;
  53. }
  54. project.AddFrameworkToProject(targetGuidToAddFramework, AuthenticationServicesFramework, true);
  55. project.AddCapability(mainTargetGuid, capabilityType, entitlementFilePath, false);
  56. }
  57. }
  58. }
  59. }
  60. #endif