使用PostProcessBuild设定Unity产生的Xcode Project

简单来说就是unity提供一套api去修改xcode项目工程配置以及修改plist文件内容(当unity build结束后, 会自动回调OnPostProcessBuild).

以下是一些用到的配置处理:

ENABLE_BITCODE
AddFramework
https
NSPhotoLibraryUsageDescription
 1 [PostProcessBuild]
 2 public static void OnPostprocessBuild(BuildTarget BuildTarget, string path)
 3 {
 4     if (BuildTarget == BuildTarget.iOS)
 5     {
 6         UnityEngine.Debug.Log("XCodePostProcess: Starting to perform post build tasks for iOS platform.");
 7                 
 8         /*======== projPath ========*/
 9         string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
10 
11         PBXProject proj = new PBXProject();
12         proj.ReadFromFile(projPath);
13 
14         string target = proj.TargetGuidByName("Unity-iPhone");
15 
16         // ENABLE_BITCODE=False
17         proj.SetBuildProperty(target, "ENABLE_BITCODE", "false");            
18 
19         // add extra framework(s)
20         proj.AddFrameworkToProject(target, "Security.framework", false);
21         proj.AddFrameworkToProject(target, "CoreTelephony.framework", true);
22         proj.AddFrameworkToProject(target, "libz.tbd", true);
23 
24         // rewrite to file
25         File.WriteAllText(projPath, proj.WriteToString());
26         
27         string plistPath = path + "/Info.plist";
28         PlistDocument plist = new PlistDocument();
29         plist.ReadFromString(File.ReadAllText(plistPath));
30                 
31         // Get root
32         PlistElementDict rootDict = plist.root;
33 
34         /* ipad 关闭分屏 */
35         rootDict.SetBoolean("UIRequiresFullScreen", true);
36 
37         var now = System.DateTime.Now;
38         string time = string.Format("{0}_{1}_{2} {3}:{4}:{5}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
39         /* 设置Build值 */
40         rootDict.SetString("CFBundleVersion", string.Format("{0}({1})", GlobalVars.VERSION, time));
41 
42         /* iOS9所有的app对外http协议默认要求改成https */
43         // Add value of NSAppTransportSecurity in Xcode plist
44         var atsKey = "NSAppTransportSecurity";
45                 
46         PlistElementDict dictTmp = rootDict.CreateDict( atsKey );
47         dictTmp.SetBoolean( "NSAllowsArbitraryLoads", true);
48 
49         // location native development region 
50         rootDict.SetString("CFBundleDevelopmentRegion", "zh_CN");
51 
52         // for share sdk 截屏
53         rootDict.SetString("NSPhotoLibraryUsageDescription", "We need use photo library usage");
54 
55         // Write to file
56         File.WriteAllText(plistPath, plist.WriteToString());
57 
58     }
59 }


在Info.plist里添加URL Scheme:

 1 /*======== plist ========*/
 2 string plistPath = path + "/Info.plist";
 3 PlistDocument plist = new PlistDocument();
 4 plist.ReadFromString(File.ReadAllText(plistPath));
 5                 
 6 // Get root
 7 PlistElementDict rootDict = plist.root;
 8 
 9 // URL schemes 追加
10 var urlTypeArray = plist.root.CreateArray("CFBundleURLTypes");
11 var urlTypeDict = urlTypeArray.AddDict();
12 urlTypeDict.SetString("CFBundleTypeRole", "Editor");
13 urlTypeDict.SetString("CFBundleURLName", "OpenApp");
14 var urlScheme = urlTypeDict.CreateArray("CFBundleURLSchemes");
15 urlScheme.AddString("sampleApp");
16                 
17 urlTypeDict = urlTypeArray.AddDict();
18 urlTypeDict.SetString("CFBundleURLName", "com.abc.sampleApp");
19 urlScheme = urlTypeDict.CreateArray("CFBundleURLSchemes");
20 urlScheme.AddString("sampleApp2");

 

有些第三方的sdk需要在appController里加一些“料”,比如Adjust SDK的deeplink功能,需要在openUrl里加[Adjust appWillOpenUrl:url];,也需要在continueUserActivity函数里作相应处理。这里的处理参考了雨松大大的博客。

首先是XClass这个类:

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.IO;
 5 
 6 namespace UnityEditor.XCodeEditor
 7 {
 8     public partial class XClass : System.IDisposable
 9     {
10 
11         private string filePath;
12 
13         public XClass(string fPath)
14         {
15             filePath = fPath;
16             if (!System.IO.File.Exists(filePath))
17             {
18                 Debug.LogError(filePath + "not found in path.");
19                 return;
20             }
21         }
22 
23         public void WriteBelow(string below, string text)
24         {
25             StreamReader streamReader = new StreamReader(filePath);
26             string text_all = streamReader.ReadToEnd();
27             streamReader.Close();
28 
29             int beginIndex = text_all.IndexOf(below);
30             if (beginIndex == -1)
31             {
32                 Debug.LogError(filePath + " not found sign in " + below);
33                 return;
34             }
35 
36             int endIndex = text_all.LastIndexOf("\n", beginIndex + below.Length);
37 
38             text_all = text_all.Substring(0, endIndex) + "\n" + text + "\n" + text_all.Substring(endIndex);
39 
40             StreamWriter streamWriter = new StreamWriter(filePath);
41             streamWriter.Write(text_all);
42             streamWriter.Close();
43         }
44 
45         public void Replace(string below, string newText)
46         {
47             StreamReader streamReader = new StreamReader(filePath);
48             string text_all = streamReader.ReadToEnd();
49             streamReader.Close();
50 
51             int beginIndex = text_all.IndexOf(below);
52             if (beginIndex == -1)
53             {
54                 Debug.LogError(filePath + " not found sign in " + below);
55                 return;
56             }
57 
58             text_all = text_all.Replace(below, newText);
59             StreamWriter streamWriter = new StreamWriter(filePath);
60             streamWriter.Write(text_all);
61             streamWriter.Close();
62 
63         }
64 
65         public void Dispose()
66         {
67 
68         }
69     }
70 }

然后还是在OnPostprocessBuild里进行hack:

1 string xcodePath = Path.GetFullPath (path);
2 UnityEditor.XCodeEditor.XClass UnityAppController = new UnityEditor.XCodeEditor.XClass(xcodePath + "/Classes/UnityAppController.mm");
3 UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"", "#include \"Adjust.h\"");
4 UnityAppController.WriteBelow("AppController_SendNotificationWithArg(kUnityOnOpenURL, notifData);","[Adjust appWillOpenUrl:url];");
5 UnityAppController.WriteBelow("SensorsCleanup();\n}", "- (BOOL)application:(UIApplication*)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * _Nullable))restorationHandler\r{\rif ([[userActivity activityType] isEqualToString:NSUserActivityTypeBrowsingWeb])\r{\rNSURL *url = [userActivity webpageURL];\rNSURL *oldStyleDeepLink = [Adjust convertUniversalLink:url scheme:@\"sampleApp\"];\r[Adjust appWillOpenUrl:url];\r}\rreturn YES;\r}");

 还在研究怎么加XCode Entitlement文件中。。。

posted on 2017-05-25 16:54  pandawuwyj  阅读(9854)  评论(1编辑  收藏  举报

导航