ProjectCapabilityManager.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. using System;
  2. using System.IO;
  3. namespace ChillyRoom.UnityEditor.iOS.Xcode
  4. {
  5. // This class is here to help you add capabilities to your Xcode project.
  6. // Because capabilities modify the PBXProject, the entitlements file and/or the Info.plist and not consistently,
  7. // it can be tedious.
  8. // Therefore this class open the PBXProject that is always modify by capabilities and open Entitlement and info.plist only when needed.
  9. // For optimisation reasons, we write the file only in the close method.
  10. // If you don't call it the file will not be written.
  11. public class ProjectCapabilityManager
  12. {
  13. private readonly string m_BuildPath;
  14. private readonly string m_TargetGuid;
  15. private readonly string m_PBXProjectPath;
  16. private readonly string m_EntitlementFilePath;
  17. private PlistDocument m_Entitlements;
  18. private PlistDocument m_InfoPlist;
  19. protected internal PBXProject project;
  20. // Create the manager with the required parameter to open files and set the properties in the write place.
  21. public ProjectCapabilityManager(string pbxProjectPath, string entitlementFilePath, string targetName)
  22. {
  23. m_BuildPath = Directory.GetParent(Path.GetDirectoryName(pbxProjectPath)).FullName;
  24. m_EntitlementFilePath = entitlementFilePath;
  25. m_PBXProjectPath = pbxProjectPath;
  26. project = new PBXProject();
  27. project.ReadFromString(File.ReadAllText(m_PBXProjectPath));
  28. m_TargetGuid = project.TargetGuidByName(targetName);
  29. }
  30. // Write the actual file to the disk.
  31. // If you don't call this method nothing will change.
  32. public void WriteToFile()
  33. {
  34. File.WriteAllText(m_PBXProjectPath, project.WriteToString());
  35. if (m_Entitlements != null)
  36. m_Entitlements.WriteToFile(PBXPath.Combine(m_BuildPath, m_EntitlementFilePath));
  37. if (m_InfoPlist != null)
  38. m_InfoPlist.WriteToFile(PBXPath.Combine(m_BuildPath, "Info.plist"));
  39. }
  40. // Add the iCloud capability with the desired options.
  41. public void AddiCloud(bool keyValueStorage, bool iCloudDocument, string[] customContainers)
  42. {
  43. var ent = GetOrCreateEntitlementDoc();
  44. var val = (ent.root[ICloudEntitlements.ContainerIdValue] = new PlistElementArray()) as PlistElementArray;
  45. if (iCloudDocument)
  46. {
  47. val.values.Add(new PlistElementString(ICloudEntitlements.ContainerIdValue));
  48. var ser = (ent.root[ICloudEntitlements.ServicesKey] = new PlistElementArray()) as PlistElementArray;
  49. ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesKitValue));
  50. ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesDocValue));
  51. var ubiquity = (ent.root[ICloudEntitlements.UbiquityContainerIdKey] = new PlistElementArray()) as PlistElementArray;
  52. ubiquity.values.Add(new PlistElementString(ICloudEntitlements.UbiquityContainerIdValue));
  53. for (var i = 0; i < customContainers.Length; i++)
  54. {
  55. ser.values.Add(new PlistElementString(customContainers[i]));
  56. }
  57. }
  58. if (keyValueStorage)
  59. {
  60. ent.root[ICloudEntitlements.KeyValueStoreKey] = new PlistElementString(ICloudEntitlements.KeyValueStoreValue);
  61. }
  62. project.AddCapability(m_TargetGuid, PBXCapabilityType.iCloud, m_EntitlementFilePath, iCloudDocument);
  63. }
  64. // Add Push (or remote) Notifications capability to your project
  65. public void AddPushNotifications(bool development)
  66. {
  67. GetOrCreateEntitlementDoc().root[PushNotificationEntitlements.Key] = new PlistElementString(development ? PushNotificationEntitlements.DevelopmentValue : PushNotificationEntitlements.ProductionValue);
  68. project.AddCapability(m_TargetGuid, PBXCapabilityType.PushNotifications, m_EntitlementFilePath);
  69. }
  70. // Add GameCenter capability to the project.
  71. public void AddGameCenter()
  72. {
  73. var arr = (GetOrCreateInfoDoc().root[GameCenterInfo.Key] ?? (GetOrCreateInfoDoc().root[GameCenterInfo.Key] = new PlistElementArray())) as PlistElementArray;
  74. arr.values.Add(new PlistElementString(GameCenterInfo.Value));
  75. project.AddCapability(m_TargetGuid, PBXCapabilityType.GameCenter);
  76. }
  77. // Add Wallet capability to the project.
  78. public void AddWallet(string[] passSubset)
  79. {
  80. var arr = (GetOrCreateEntitlementDoc().root[WalletEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  81. if ((passSubset == null || passSubset.Length == 0) && arr != null)
  82. {
  83. arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + WalletEntitlements.BaseValue));
  84. }
  85. else
  86. {
  87. for (var i = 0; i < passSubset.Length; i++)
  88. {
  89. if (arr != null)
  90. arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + passSubset[i]));
  91. }
  92. }
  93. project.AddCapability(m_TargetGuid, PBXCapabilityType.Wallet, m_EntitlementFilePath);
  94. }
  95. // Add Siri capability to the project.
  96. public void AddSiri()
  97. {
  98. GetOrCreateEntitlementDoc().root[SiriEntitlements.Key] = new PlistElementBoolean(true);
  99. project.AddCapability(m_TargetGuid, PBXCapabilityType.Siri, m_EntitlementFilePath);
  100. }
  101. // Add Apple Pay capability to the project.
  102. public void AddApplePay(string[] merchants)
  103. {
  104. var arr = (GetOrCreateEntitlementDoc().root[ApplePayEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  105. for (var i = 0; i < merchants.Length; i++)
  106. {
  107. arr.values.Add(new PlistElementString(merchants[i]));
  108. }
  109. project.AddCapability(m_TargetGuid, PBXCapabilityType.ApplePay, m_EntitlementFilePath);
  110. }
  111. // Add In App Purchase capability to the project.
  112. public void AddInAppPurchase()
  113. {
  114. project.AddCapability(m_TargetGuid, PBXCapabilityType.InAppPurchase);
  115. }
  116. // Add Maps capability to the project.
  117. public void AddMaps(MapsOptions options)
  118. {
  119. var bundleArr = (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] ?? (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] = new PlistElementArray())) as PlistElementArray;
  120. bundleArr.values.Add(new PlistElementDict());
  121. PlistElementDict bundleDic = GetOrCreateUniqueDictElementInArray(bundleArr);
  122. bundleDic[MapsInfo.BundleNameKey] = new PlistElementString(MapsInfo.BundleNameValue);
  123. var bundleTypeArr = (bundleDic[MapsInfo.BundleTypeKey] ?? (bundleDic[MapsInfo.BundleTypeKey] = new PlistElementArray())) as PlistElementArray;
  124. GetOrCreateStringElementInArray(bundleTypeArr, MapsInfo.BundleTypeValue);
  125. var optionArr = (GetOrCreateInfoDoc().root[MapsInfo.ModeKey] ??
  126. (GetOrCreateInfoDoc().root[MapsInfo.ModeKey] = new PlistElementArray())) as PlistElementArray;
  127. if ((options & MapsOptions.Airplane) == MapsOptions.Airplane)
  128. {
  129. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePlaneValue);
  130. }
  131. if ((options & MapsOptions.Bike) == MapsOptions.Bike)
  132. {
  133. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBikeValue);
  134. }
  135. if ((options & MapsOptions.Bus) == MapsOptions.Bus)
  136. {
  137. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBusValue);
  138. }
  139. if ((options & MapsOptions.Car) == MapsOptions.Car)
  140. {
  141. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeCarValue);
  142. }
  143. if ((options & MapsOptions.Ferry) == MapsOptions.Ferry)
  144. {
  145. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeFerryValue);
  146. }
  147. if ((options & MapsOptions.Other) == MapsOptions.Other)
  148. {
  149. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeOtherValue);
  150. }
  151. if ((options & MapsOptions.Pedestrian) == MapsOptions.Pedestrian)
  152. {
  153. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePedestrianValue);
  154. }
  155. if ((options & MapsOptions.RideSharing) == MapsOptions.RideSharing)
  156. {
  157. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeRideShareValue);
  158. }
  159. if ((options & MapsOptions.StreetCar) == MapsOptions.StreetCar)
  160. {
  161. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeStreetCarValue);
  162. }
  163. if ((options & MapsOptions.Subway) == MapsOptions.Subway)
  164. {
  165. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeSubwayValue);
  166. }
  167. if ((options & MapsOptions.Taxi) == MapsOptions.Taxi)
  168. {
  169. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTaxiValue);
  170. }
  171. if ((options & MapsOptions.Train) == MapsOptions.Train)
  172. {
  173. GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTrainValue);
  174. }
  175. project.AddCapability(m_TargetGuid, PBXCapabilityType.Maps);
  176. }
  177. // Add Personal VPN capability to the project.
  178. public void AddPersonalVPN()
  179. {
  180. var arr = (GetOrCreateEntitlementDoc().root[VPNEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  181. arr.values.Add(new PlistElementString(VPNEntitlements.Value));
  182. project.AddCapability(m_TargetGuid, PBXCapabilityType.PersonalVPN, m_EntitlementFilePath);
  183. }
  184. // Add Background capability to the project with the options wanted.
  185. public void AddBackgroundModes(BackgroundModesOptions options)
  186. {
  187. var optionArr = (GetOrCreateInfoDoc().root[BackgroundInfo.Key] ??
  188. (GetOrCreateInfoDoc().root[BackgroundInfo.Key] = new PlistElementArray())) as PlistElementArray;
  189. if ((options & BackgroundModesOptions.ActsAsABluetoothLEAccessory) == BackgroundModesOptions.ActsAsABluetoothLEAccessory)
  190. {
  191. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeActsBluetoothValue);
  192. }
  193. if ((options & BackgroundModesOptions.AudioAirplayPiP) == BackgroundModesOptions.AudioAirplayPiP)
  194. {
  195. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeAudioValue);
  196. }
  197. if ((options & BackgroundModesOptions.BackgroundFetch) == BackgroundModesOptions.BackgroundFetch)
  198. {
  199. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeFetchValue);
  200. }
  201. if ((options & BackgroundModesOptions.ExternalAccessoryCommunication) == BackgroundModesOptions.ExternalAccessoryCommunication)
  202. {
  203. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeExtAccessoryValue);
  204. }
  205. if ((options & BackgroundModesOptions.LocationUpdates) == BackgroundModesOptions.LocationUpdates)
  206. {
  207. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeLocationValue);
  208. }
  209. if ((options & BackgroundModesOptions.NewsstandDownloads) == BackgroundModesOptions.NewsstandDownloads)
  210. {
  211. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeNewsstandValue);
  212. }
  213. if ((options & BackgroundModesOptions.RemoteNotifications) == BackgroundModesOptions.RemoteNotifications)
  214. {
  215. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModePushValue);
  216. }
  217. if ((options & BackgroundModesOptions.VoiceOverIP) == BackgroundModesOptions.VoiceOverIP)
  218. {
  219. GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeVOIPValue);
  220. }
  221. project.AddCapability(m_TargetGuid, PBXCapabilityType.BackgroundModes);
  222. }
  223. // Add Keychain Sharing capability to the project with a list of groups.
  224. public void AddKeychainSharing(string[] accessGroups)
  225. {
  226. var arr = (GetOrCreateEntitlementDoc().root[KeyChainEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  227. if (accessGroups != null)
  228. {
  229. for (var i = 0; i < accessGroups.Length; i++)
  230. {
  231. arr.values.Add(new PlistElementString(accessGroups[i]));
  232. }
  233. }
  234. else
  235. {
  236. arr.values.Add(new PlistElementString(KeyChainEntitlements.DefaultValue));
  237. }
  238. project.AddCapability(m_TargetGuid, PBXCapabilityType.KeychainSharing, m_EntitlementFilePath);
  239. }
  240. // Add Inter App Audio capability to the project.
  241. public void AddInterAppAudio()
  242. {
  243. GetOrCreateEntitlementDoc().root[AudioEntitlements.Key] = new PlistElementBoolean(true);
  244. project.AddCapability(m_TargetGuid, PBXCapabilityType.InterAppAudio, m_EntitlementFilePath);
  245. }
  246. // Add Associated Domains capability to the project.
  247. public void AddAssociatedDomains(string[] domains)
  248. {
  249. var arr = (GetOrCreateEntitlementDoc().root[AssociatedDomainsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  250. for (var i = 0; i < domains.Length; i++)
  251. {
  252. arr.values.Add(new PlistElementString(domains[i]));
  253. }
  254. project.AddCapability(m_TargetGuid, PBXCapabilityType.AssociatedDomains, m_EntitlementFilePath);
  255. }
  256. // Add App Groups capability to the project.
  257. public void AddAppGroups(string[] groups)
  258. {
  259. var arr = (GetOrCreateEntitlementDoc().root[AppGroupsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
  260. for (var i = 0; i < groups.Length; i++)
  261. {
  262. arr.values.Add(new PlistElementString(groups[i]));
  263. }
  264. project.AddCapability(m_TargetGuid, PBXCapabilityType.AppGroups, m_EntitlementFilePath);
  265. }
  266. // Add HomeKit capability to the project.
  267. public void AddHomeKit()
  268. {
  269. GetOrCreateEntitlementDoc().root[HomeKitEntitlements.Key] = new PlistElementBoolean(true);
  270. project.AddCapability(m_TargetGuid, PBXCapabilityType.HomeKit, m_EntitlementFilePath);
  271. }
  272. // Add Data Protection capability to the project.
  273. public void AddDataProtection()
  274. {
  275. GetOrCreateEntitlementDoc().root[DataProtectionEntitlements.Key] = new PlistElementString(DataProtectionEntitlements.Value);
  276. project.AddCapability(m_TargetGuid, PBXCapabilityType.DataProtection, m_EntitlementFilePath);
  277. }
  278. // Add HealthKit capability to the project.
  279. public void AddHealthKit()
  280. {
  281. var capabilityArr = (GetOrCreateInfoDoc().root[HealthInfo.Key] ??
  282. (GetOrCreateInfoDoc().root[HealthInfo.Key] = new PlistElementArray())) as PlistElementArray;
  283. GetOrCreateStringElementInArray(capabilityArr, HealthInfo.Value);
  284. GetOrCreateEntitlementDoc().root[HealthKitEntitlements.Key] = new PlistElementBoolean(true);
  285. project.AddCapability(m_TargetGuid, PBXCapabilityType.HealthKit, m_EntitlementFilePath);
  286. }
  287. // Add Wireless Accessory Configuration capability to the project.
  288. public void AddWirelessAccessoryConfiguration()
  289. {
  290. GetOrCreateEntitlementDoc().root[WirelessAccessoryConfigurationEntitlements.Key] = new PlistElementBoolean(true);
  291. project.AddCapability(m_TargetGuid, PBXCapabilityType.WirelessAccessoryConfiguration, m_EntitlementFilePath);
  292. }
  293. private PlistDocument GetOrCreateEntitlementDoc()
  294. {
  295. if (m_Entitlements == null)
  296. {
  297. m_Entitlements = new PlistDocument();
  298. string[] entitlementsFiles = Directory.GetFiles(m_BuildPath, m_EntitlementFilePath);
  299. if (entitlementsFiles.Length > 0)
  300. {
  301. m_Entitlements.ReadFromFile(entitlementsFiles[0]);
  302. }
  303. else
  304. {
  305. m_Entitlements.Create();
  306. }
  307. }
  308. return m_Entitlements;
  309. }
  310. private PlistDocument GetOrCreateInfoDoc()
  311. {
  312. if (m_InfoPlist == null)
  313. {
  314. m_InfoPlist = new PlistDocument();
  315. string[] infoFiles = Directory.GetFiles(m_BuildPath + "/", "Info.plist");
  316. if (infoFiles.Length > 0)
  317. {
  318. m_InfoPlist.ReadFromFile(infoFiles[0]);
  319. }
  320. else
  321. {
  322. m_InfoPlist.Create();
  323. }
  324. }
  325. return m_InfoPlist;
  326. }
  327. private PlistElementString GetOrCreateStringElementInArray(PlistElementArray root, string value)
  328. {
  329. PlistElementString r = null;
  330. var c = root.values.Count;
  331. var exist = false;
  332. for (var i = 0; i < c; i++)
  333. {
  334. if (root.values[i] is PlistElementString && (root.values[i] as PlistElementString).value == value)
  335. {
  336. r = root.values[i] as PlistElementString;
  337. exist = true;
  338. }
  339. }
  340. if (!exist)
  341. {
  342. r = new PlistElementString(value);
  343. root.values.Add(r);
  344. }
  345. return r;
  346. }
  347. private PlistElementDict GetOrCreateUniqueDictElementInArray(PlistElementArray root)
  348. {
  349. PlistElementDict r;
  350. if (root.values.Count == 0)
  351. {
  352. r = root.values[0] as PlistElementDict;
  353. }
  354. else
  355. {
  356. r = new PlistElementDict();
  357. root.values.Add(r);
  358. }
  359. return r;
  360. }
  361. }
  362. // The list of options available for Background Mode.
  363. [Flags]
  364. [Serializable]
  365. public enum BackgroundModesOptions
  366. {
  367. None = 0,
  368. AudioAirplayPiP = 1<<0,
  369. LocationUpdates = 1<<1,
  370. VoiceOverIP = 1<<2,
  371. NewsstandDownloads = 1<<3,
  372. ExternalAccessoryCommunication = 1<<4,
  373. UsesBluetoothLEAccessory = 1<<5,
  374. ActsAsABluetoothLEAccessory = 1<<6,
  375. BackgroundFetch = 1<<7,
  376. RemoteNotifications = 1<<8
  377. }
  378. // The list of options available for Maps.
  379. [Serializable]
  380. [Flags]
  381. public enum MapsOptions
  382. {
  383. None = 0,
  384. Airplane = 1<<0,
  385. Bike = 1<<1,
  386. Bus = 1<<2,
  387. Car = 1<<3,
  388. Ferry = 1<<4,
  389. Pedestrian = 1<<5,
  390. RideSharing = 1<<6,
  391. StreetCar = 1<<7,
  392. Subway = 1<<8,
  393. Taxi = 1<<9,
  394. Train = 1<<10,
  395. Other = 1<<11
  396. }
  397. /* Follows the large quantity of string used as key and value all over the place in the info.plist or entitlements file. */
  398. internal class GameCenterInfo
  399. {
  400. internal static readonly string Key = "UIRequiredDeviceCapabilities";
  401. internal static readonly string Value = "gamekit";
  402. }
  403. internal class MapsInfo
  404. {
  405. internal static readonly string BundleKey = "CFBundleDocumentTypes";
  406. internal static readonly string BundleNameKey = "CFBundleTypeName";
  407. internal static readonly string BundleNameValue = "MKDirectionsRequest";
  408. internal static readonly string BundleTypeKey = "LSItemContentTypes";
  409. internal static readonly string BundleTypeValue = "com.apple.maps.directionsrequest";
  410. internal static readonly string ModeKey = "MKDirectionsApplicationSupportedModes";
  411. internal static readonly string ModePlaneValue = "MKDirectionsModePlane";
  412. internal static readonly string ModeBikeValue = "MKDirectionsModeBike";
  413. internal static readonly string ModeBusValue = "MKDirectionsModeBus";
  414. internal static readonly string ModeCarValue = "MKDirectionsModeCar";
  415. internal static readonly string ModeFerryValue = "MKDirectionsModeFerry";
  416. internal static readonly string ModeOtherValue = "MKDirectionsModeOther";
  417. internal static readonly string ModePedestrianValue = "MKDirectionsModePedestrian";
  418. internal static readonly string ModeRideShareValue = "MKDirectionsModeRideShare";
  419. internal static readonly string ModeStreetCarValue = "MKDirectionsModeStreetCar";
  420. internal static readonly string ModeSubwayValue = "MKDirectionsModeSubway";
  421. internal static readonly string ModeTaxiValue = "MKDirectionsModeTaxi";
  422. internal static readonly string ModeTrainValue = "MKDirectionsModeTrain";
  423. }
  424. internal class BackgroundInfo
  425. {
  426. internal static readonly string Key = "UIBackgroundModes";
  427. internal static readonly string ModeAudioValue = "audio";
  428. internal static readonly string ModeBluetoothValue = "bluetooth-central";
  429. internal static readonly string ModeActsBluetoothValue = "bluetooth-peripheral";
  430. internal static readonly string ModeExtAccessoryValue = "external-accessory";
  431. internal static readonly string ModeFetchValue = "fetch";
  432. internal static readonly string ModeLocationValue = "location";
  433. internal static readonly string ModeNewsstandValue = "newsstand-content";
  434. internal static readonly string ModePushValue = "remote-notification";
  435. internal static readonly string ModeVOIPValue = "voip";
  436. }
  437. internal class HealthInfo
  438. {
  439. internal static readonly string Key = "UIRequiredDeviceCapabilities";
  440. internal static readonly string Value = "healthkit";
  441. }
  442. internal class ICloudEntitlements
  443. {
  444. internal static readonly string ContainerIdKey = "com.apple.developer.icloud-container-identifiers";
  445. internal static readonly string UbiquityContainerIdKey = "com.apple.developer.ubiquity-container-identifiers";
  446. internal static readonly string ContainerIdValue = "iCloud.$(CFBundleIdentifier)";
  447. internal static readonly string UbiquityContainerIdValue = "iCloud.$(CFBundleIdentifier)";
  448. internal static readonly string ServicesKey = "com.apple.developer.icloud-services";
  449. internal static readonly string ServicesDocValue = "CloudDocuments";
  450. internal static readonly string ServicesKitValue = "CloudKit";
  451. internal static readonly string KeyValueStoreKey = "com.apple.developer.ubiquity-kvstore-identifier";
  452. internal static readonly string KeyValueStoreValue = "$(TeamIdentifierPrefix)$(CFBundleIdentifier)";
  453. }
  454. internal class PushNotificationEntitlements
  455. {
  456. internal static readonly string Key = "aps-environment";
  457. internal static readonly string DevelopmentValue = "development";
  458. internal static readonly string ProductionValue = "production";
  459. }
  460. internal class WalletEntitlements
  461. {
  462. internal static readonly string Key = "com.apple.developer.pass-type-identifiers";
  463. internal static readonly string BaseValue = "$(TeamIdentifierPrefix)";
  464. internal static readonly string DefaultValue = "*";
  465. }
  466. internal class SiriEntitlements
  467. {
  468. internal static readonly string Key = "com.apple.developer.siri";
  469. }
  470. internal class ApplePayEntitlements
  471. {
  472. internal static readonly string Key = "com.apple.developer.in-app-payments";
  473. }
  474. internal class VPNEntitlements
  475. {
  476. internal static readonly string Key = "com.apple.developer.networking.vpn.api";
  477. internal static readonly string Value = "allow-vpn";
  478. }
  479. internal class KeyChainEntitlements
  480. {
  481. internal static readonly string Key = "keychain-access-groups";
  482. internal static readonly string DefaultValue = "$(AppIdentifierPrefix)$(CFBundleIdentifier)";
  483. }
  484. internal class AudioEntitlements
  485. {
  486. internal static readonly string Key = "inter-app-audio";
  487. }
  488. internal class AssociatedDomainsEntitlements
  489. {
  490. // value is an array of string of domains
  491. internal static readonly string Key = "com.apple.developer.associated-domains";
  492. }
  493. internal class AppGroupsEntitlements
  494. {
  495. // value is an array of string of groups
  496. internal static readonly string Key = "com.apple.security.application-groups";
  497. }
  498. internal class HomeKitEntitlements
  499. {
  500. // value is bool true.
  501. internal static readonly string Key = "com.apple.developer.homekit";
  502. }
  503. internal class DataProtectionEntitlements
  504. {
  505. internal static readonly string Key = "com.apple.developer.default-data-protection";
  506. internal static readonly string Value = "NSFileProtectionComplete";
  507. }
  508. internal class HealthKitEntitlements
  509. {
  510. // value is bool true.
  511. internal static readonly string Key = "com.apple.developer.healthkit";
  512. }
  513. internal class WirelessAccessoryConfigurationEntitlements
  514. {
  515. // value is bool true.
  516. internal static readonly string Key = "com.apple.external-accessory.wireless-configuration";
  517. }
  518. }