使用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) 编辑 收藏 举报