PListProcessor.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright (C) 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #if UNITY_IPHONE || UNITY_IOS
  15. using System;
  16. using System.Collections.Generic;
  17. using System.IO;
  18. using System.Xml;
  19. using UnityEditor;
  20. using UnityEditor.Callbacks;
  21. using UnityEditor.iOS.Xcode;
  22. using UnityEngine;
  23. using GoogleMobileAds.Editor;
  24. public static class PListProcessor
  25. {
  26. private const string KEY_SK_ADNETWORK_ITEMS = "SKAdNetworkItems";
  27. private const string KEY_SK_ADNETWORK_ID = "SKAdNetworkIdentifier";
  28. private const string SKADNETWORKS_RELATIVE_PATH = "GoogleMobileAds/Editor/GoogleMobileAdsSKAdNetworkItems.xml";
  29. [PostProcessBuild]
  30. public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
  31. {
  32. string plistPath = Path.Combine(path, "Info.plist");
  33. PlistDocument plist = new PlistDocument();
  34. plist.ReadFromFile(plistPath);
  35. GoogleMobileAdsSettings instance = GoogleMobileAdsSettings.LoadInstance();
  36. string appId = instance.GoogleMobileAdsIOSAppId;
  37. if (appId.Length == 0)
  38. {
  39. NotifyBuildFailure(
  40. "iOS Google Mobile Ads app ID is empty. Please enter a valid app ID to run ads properly.");
  41. }
  42. else
  43. {
  44. plist.root.SetString("GADApplicationIdentifier", appId);
  45. }
  46. if (instance.DelayAppMeasurementInit)
  47. {
  48. plist.root.SetBoolean("GADDelayAppMeasurementInit", true);
  49. }
  50. List<string> skNetworkIds = ReadSKAdNetworkIdentifiersFromXML();
  51. if (skNetworkIds.Count > 0)
  52. {
  53. AddSKAdNetworkIdentifier(plist, skNetworkIds);
  54. }
  55. File.WriteAllText(plistPath, plist.WriteToString());
  56. }
  57. private static PlistElementArray GetSKAdNetworkItemsArray(PlistDocument document)
  58. {
  59. PlistElementArray array;
  60. if (document.root.values.ContainsKey(KEY_SK_ADNETWORK_ITEMS))
  61. {
  62. try
  63. {
  64. PlistElement element;
  65. document.root.values.TryGetValue(KEY_SK_ADNETWORK_ITEMS, out element);
  66. array = element.AsArray();
  67. }
  68. #pragma warning disable 0168
  69. catch (Exception e)
  70. #pragma warning restore 0168
  71. {
  72. // The element is not an array type.
  73. array = null;
  74. }
  75. }
  76. else
  77. {
  78. array = document.root.CreateArray(KEY_SK_ADNETWORK_ITEMS);
  79. }
  80. return array;
  81. }
  82. private static List<string> ReadSKAdNetworkIdentifiersFromXML()
  83. {
  84. List<string> skAdNetworkItems = new List<string>();
  85. string path = Path.Combine(Application.dataPath, SKADNETWORKS_RELATIVE_PATH);
  86. if (AssetDatabase.IsValidFolder("Packages/com.google.ads.mobile"))
  87. {
  88. path = Path.Combine("Packages/com.google.ads.mobile", SKADNETWORKS_RELATIVE_PATH);
  89. }
  90. try
  91. {
  92. if (!File.Exists(path))
  93. {
  94. throw new FileNotFoundException();
  95. }
  96. using (FileStream fs = File.OpenRead(path))
  97. {
  98. XmlDocument document = new XmlDocument();
  99. document.Load(fs);
  100. XmlNode root = document.FirstChild;
  101. XmlNodeList nodes = root.SelectNodes(KEY_SK_ADNETWORK_ID);
  102. foreach (XmlNode node in nodes)
  103. {
  104. skAdNetworkItems.Add(node.InnerText);
  105. }
  106. }
  107. }
  108. #pragma warning disable 0168
  109. catch (FileNotFoundException e)
  110. #pragma warning restore 0168
  111. {
  112. NotifyBuildFailure("GoogleMobileAdsSKAdNetworkItems.xml not found", false);
  113. }
  114. catch (IOException e)
  115. {
  116. NotifyBuildFailure("Failed to read GoogleMobileAdsSKAdNetworkIds.xml: " + e.Message, false);
  117. }
  118. return skAdNetworkItems;
  119. }
  120. private static void AddSKAdNetworkIdentifier(PlistDocument document, List<string> skAdNetworkIds)
  121. {
  122. PlistElementArray array = GetSKAdNetworkItemsArray(document);
  123. if (array != null)
  124. {
  125. foreach (string id in skAdNetworkIds)
  126. {
  127. if (!ContainsSKAdNetworkIdentifier(array, id))
  128. {
  129. PlistElementDict added = array.AddDict();
  130. added.SetString(KEY_SK_ADNETWORK_ID, id);
  131. }
  132. }
  133. }
  134. else
  135. {
  136. NotifyBuildFailure("SKAdNetworkItems element already exists in Info.plist, but is not an array.", false);
  137. }
  138. }
  139. private static bool ContainsSKAdNetworkIdentifier(PlistElementArray skAdNetworkItemsArray, string id)
  140. {
  141. foreach (PlistElement elem in skAdNetworkItemsArray.values)
  142. {
  143. try
  144. {
  145. PlistElementDict elemInDict = elem.AsDict();
  146. PlistElement value;
  147. bool identifierExists = elemInDict.values.TryGetValue(KEY_SK_ADNETWORK_ID, out value);
  148. if (identifierExists && value.AsString().Equals(id))
  149. {
  150. return true;
  151. }
  152. }
  153. #pragma warning disable 0168
  154. catch (Exception e)
  155. #pragma warning restore 0168
  156. {
  157. // Do nothing
  158. }
  159. }
  160. return false;
  161. }
  162. private static void NotifyBuildFailure(string message, bool showOpenSettingsButton = true)
  163. {
  164. string dialogTitle = "Google Mobile Ads";
  165. string dialogMessage = "Error: " + message;
  166. if (showOpenSettingsButton)
  167. {
  168. bool openSettings = EditorUtility.DisplayDialog(
  169. dialogTitle, dialogMessage, "Open Settings", "Close");
  170. if (openSettings)
  171. {
  172. GoogleMobileAdsSettingsEditor.OpenInspector();
  173. }
  174. }
  175. else
  176. {
  177. EditorUtility.DisplayDialog(dialogTitle, dialogMessage, "Close");
  178. }
  179. ThrowBuildException("[GoogleMobileAds] " + message);
  180. }
  181. private static void ThrowBuildException(string message)
  182. {
  183. #if UNITY_2017_1_OR_NEWER
  184. throw new BuildPlayerWindow.BuildMethodException(message);
  185. #else
  186. throw new OperationCanceledException(message);
  187. #endif
  188. }
  189. }
  190. #endif