/// <summary> /// Extracts the dict values for the Entitlements key and creates a new full .plist file /// from them (with outer plist and dict keys as well as doctype, etc...) /// </summary> public string GetEntitlementsString(string CFBundleIdentifier, out string TeamIdentifier) { Utilities.PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = Utilities.PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed string CurrentApplicationIdentifier; XCentPList.GetString("application-identifier", out CurrentApplicationIdentifier); XCentPList.GetString("com.apple.developer.team-identifier", out TeamIdentifier); // if (CurrentApplicationIdentifier.Contains("*")) { // Replace the application identifier string NewApplicationIdentifier = String.Format("{0}.{1}", ApplicationIdentifierPrefix, CFBundleIdentifier); XCentPList.SetString("application-identifier", NewApplicationIdentifier); // Replace the keychain access groups // Note: This isn't robust, it ignores the existing value in the wildcard and uses the same value for // each entry. If there is a legitimate need for more than one entry in the access group list, then // don't use a wildcard! List <string> KeyGroups = XCentPList.GetArray("keychain-access-groups", "string"); for (int i = 0; i < KeyGroups.Count; ++i) { string Entry = KeyGroups[i]; if (Entry.Contains("*")) { Entry = NewApplicationIdentifier; } KeyGroups[i] = Entry; } XCentPList.SetValueForKey("keychain-access-groups", KeyGroups); } // must have CloudKit and CloudDocuments for com.apple.developer.icloud-services // otherwise the game will not be listed in the Settings->iCloud apps menu on the device { // iOS only if (Platform == "IOS" && XCentPList.HasKey("com.apple.developer.icloud-services")) { List <string> ServicesGroups = XCentPList.GetArray("com.apple.developer.icloud-services", "string"); ServicesGroups.Clear(); ServicesGroups.Add("CloudKit"); ServicesGroups.Add("CloudDocuments"); XCentPList.SetValueForKey("com.apple.developer.icloud-services", ServicesGroups); } // For distribution builds, the entitlements from mobileprovisioning have a modified syntax if (Config.bForDistribution) { // remove the wildcards from the ubiquity-kvstore-identifier string if (XCentPList.HasKey("com.apple.developer.ubiquity-kvstore-identifier")) { string UbiquityKvstoreString; XCentPList.GetString("com.apple.developer.ubiquity-kvstore-identifier", out UbiquityKvstoreString); int DotPosition = UbiquityKvstoreString.LastIndexOf("*"); if (DotPosition >= 0) { string TeamPrefix = DotPosition > 1 ? UbiquityKvstoreString.Substring(0, DotPosition - 1) : TeamIdentifier; string NewUbiquityKvstoreIdentifier = String.Format("{0}.{1}", TeamPrefix, CFBundleIdentifier); XCentPList.SetValueForKey("com.apple.developer.ubiquity-kvstore-identifier", NewUbiquityKvstoreIdentifier); } } // remove the wildcards from the ubiquity-container-identifiers array if (XCentPList.HasKey("com.apple.developer.ubiquity-container-identifiers")) { List <string> UbiquityContainerIdentifiersGroups = XCentPList.GetArray("com.apple.developer.ubiquity-container-identifiers", "string"); for (int i = 0; i < UbiquityContainerIdentifiersGroups.Count; i++) { int DotPosition = UbiquityContainerIdentifiersGroups[i].LastIndexOf("*"); if (DotPosition >= 0) { string TeamPrefix = DotPosition > 1 ? UbiquityContainerIdentifiersGroups[i].Substring(0, DotPosition - 1) : TeamIdentifier; string NewUbiquityContainerIdentifier = String.Format("{0}.{1}", TeamPrefix, CFBundleIdentifier); UbiquityContainerIdentifiersGroups[i] = NewUbiquityContainerIdentifier; } } if (UbiquityContainerIdentifiersGroups.Count == 0) { string NewUbiquityKvstoreIdentifier = String.Format("{0}.{1}", TeamIdentifier, CFBundleIdentifier); UbiquityContainerIdentifiersGroups.Add(NewUbiquityKvstoreIdentifier); } XCentPList.SetValueForKey("com.apple.developer.ubiquity-container-identifiers", UbiquityContainerIdentifiersGroups); } // remove the wildcards from the developer.associated-domains array or string if (XCentPList.HasKey("com.apple.developer.associated-domains")) { string AssociatedDomainsString; XCentPList.GetString("com.apple.developer.associated-domains", out AssociatedDomainsString); //check if the value is string if (AssociatedDomainsString != null && AssociatedDomainsString.Contains("*")) { XCentPList.RemoveKeyValue("com.apple.developer.associated-domains"); } else { //check if the value is an array List <string> AssociatedDomainsGroup = XCentPList.GetArray("com.apple.developer.associated-domains", "string"); if (AssociatedDomainsGroup.Count == 1 && AssociatedDomainsGroup[0].Contains("*")) { XCentPList.RemoveKeyValue("com.apple.developer.associated-domains"); } } } // remove development keys - generated when the cloudkit container is in development mode XCentPList.RemoveKeyValue("com.apple.developer.icloud-container-development-container-identifiers"); } // set the icloud-container-environment according to the project settings if (XCentPList.HasKey("com.apple.developer.icloud-container-environment")) { List <string> ContainerEnvironmentGroup = XCentPList.GetArray("com.apple.developer.icloud-container-environment", "string"); if (ContainerEnvironmentGroup.Count != 0) { ContainerEnvironmentGroup.Clear(); // The new value is a string, not an array string NewContainerEnvironment = Config.bForDistribution ? "Production" : "Development"; XCentPList.SetValueForKey("com.apple.developer.icloud-container-environment", NewContainerEnvironment); } } } return(XCentPList.SaveToString()); }