Unity打IOS时会先生成一个Xcode工程,如果你需要增加一些第三方的framework那么需要手动一条一条的添加,这太烦了。。而且可能你还需要修改Plist文件,甚至还可能要修改unity自动生成的oc代码,每次打包都要修改的话,那太累了。。这篇文章就是全自动打包的第一步。。建议使用XUPorter,我在它的基础上拓展了两个类,一个用来修改plist,一个用来修改unity生成出来的OC代码。文章的最后我会给出代码。。

那么我用一个比较变态的SDK举个例子ShareSDK,它就需要自动添加framework,修改plist,还有要修改oc的代码。第一步打开XUPorter/Mods/share.projmods 文件。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
    "group": "share",
    "libs": ["libicucore.dylib","libz.1.2.5.dylib"],
    "frameworks": [
                    "SystemConfiguration.framework",
                    "QuartzCore.framework",
                    "CoreTelephony.framework",
                    "Security.framework",
                    "AdSupport.framework:optional",
                    "MessageUI.framework",
                     "StoreKit.framework",
                     "AudioToolbox.framework",
                     "QuartzCore.framework"
                   ],
    "headerpaths": [],
    "files":   [
                "ShareSDK/Connection/SinaWeiboConnection.framework",
                "ShareSDK/Connection/WeChatConnection.framework",
                "ShareSDK/Core/AGCommon.framework",
                "ShareSDK/Core/ShareSDKCoreService.framework",
                "ShareSDK/ShareSDK.framework"
                ],
    "folders": ["ShareSDK/"],    
    "excludes": ["^.*.meta$", "^.*.mdown$", "^.*.pdf$"],
    "linker_flags": []
}

 frameworks分成两种,一种是系统自带的framework还有一种是第三方的framework。 “frameworks”节点里面放的是系统自带的frameworks。”files”节点里面放的是第三方做出来的framework。 尤其是第三方的framework如果位置放的不对,就不会被xcode所引用的!切记切记!!

folders:可以把某个文件夹下的所有文件拷贝在xcode工程里面,一般sdk都会附带一些oc的代码文件,最好通过folders把oc的代码拷贝在工程里面。或者你也可以把oc的代码放在plugins下面,同样打包的时候也会拷贝进xcode工程。

unity打完IOS或者Android包以后会自动回调一个静态方法。

 
1
2
    [PostProcessBuild (100)]
    public static void OnPostProcessBuild (BuildTarget target, string pathToBuiltProject)

 自动添加framework的原理其实就是等包打完以后,在这个方法里面进行文件的操作,把需要的framework plist oc 代码拷贝进去,或者修改它们。。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using UnityEngine;
 
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.XCodeEditor;
using System.Xml;
#endif
using System.IO;
 
public static class XCodePostProcess
{
    #if UNITY_EDITOR
    [PostProcessBuild (100)]
    public static void OnPostProcessBuild (BuildTarget target, string pathToBuiltProject)
    {
        if (target != BuildTarget.iPhone) {
            Debug.LogWarning ("Target is not iPhone. XCodePostProcess will not run");
            return;
        }
 
        //得到xcode工程的路径
        string path = Path.GetFullPath (pathToBuiltProject);
 
        // Create a new project object from build target
        XCProject project = new XCProject (pathToBuiltProject);
 
        // Find and run through all projmods files to patch the project.
        // Please pay attention that ALL projmods files in your project folder will be excuted!
        //在这里面把frameworks添加在你的xcode工程里面
        string[] files = Directory.GetFiles (Application.dataPath, "*.projmods", SearchOption.AllDirectories);
        foreach (string file in files) {
            project.ApplyMod (file);
        }
 
        //增加一个编译标记。。没有的话sharesdk会报错。。
        project.AddOtherLinkerFlags("-licucore");
 
        //设置签名的证书, 第二个参数 你可以设置成你的证书
        project.overwriteBuildSetting ("CODE_SIGN_IDENTITY", "xxxxxx", "Release");
        project.overwriteBuildSetting ("CODE_SIGN_IDENTITY", "xxxxxx", "Debug");
 
        // 编辑plist 文件
        EditorPlist(path);
 
        //编辑代码文件
        EditorCode(path);
 
        // Finally save the xcode project
        project.Save ();
 
    }
 
    private static void EditorPlist(string filePath)
    {
 
        XCPlist list =new XCPlist(filePath);
        string bundle = "com.yusong.momo";
 
        string PlistAdd = @"  
            <key>CFBundleURLTypes</key>
            <array>
            <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLIconFile</key>
            <string>Icon@2x</string>
            <key>CFBundleURLName</key>
            <string>"+bundle+@"</string>
            <key>CFBundleURLSchemes</key>
            <array>
            <string>ww123456</string>
            </array>
            </dict>
            </array>";
 
        //在plist里面增加一行
        list.AddKey(PlistAdd);
        //在plist里面替换一行
        list.ReplaceKey("<string>com.yusong.${PRODUCT_NAME}</string>","<string>"+bundle+"</string>");
        //保存
        list.Save();
 
    }
 
    private static void EditorCode(string filePath)
    {
        //读取UnityAppController.mm文件
        XClass UnityAppController = new XClass(filePath + "/Classes/UnityAppController.mm");
 
        //在指定代码后面增加一行代码
        UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"","#import <ShareSDK/ShareSDK.h>");
 
        //在指定代码中替换一行
        UnityAppController.Replace("return YES;","return [ShareSDK handleOpenURL:url sourceApplication:sourceApplication annotation:annotation wxDelegate:nil];");
 
        //在指定代码后面增加一行
        UnityAppController.WriteBelow("UnityCleanup();\n}","- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url\r{\r    return [ShareSDK handleOpenURL:url wxDelegate:nil];\r}");
 
    }
 
    #endif
}

在回到ShareSDK上,在接微信平台的时候,它们需要在pList 里面增加URL types选项,这里我通过XCPlist增加一行 或者替换一行。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
 
namespace UnityEditor.XCodeEditor
{
    public partial class XCPlist : System.IDisposable
    {
 
        private string filePath;
        List<string> contents = new List<string>();
        public XCPlist(string fPath)
        {
            filePath = Path.Combine( fPath, "info.plist" );
            if( !System.IO.File.Exists( filePath ) ) {
                Debug.LogError( filePath +"路径下文件不存在" );
                return;
            }
 
            FileInfo projectFileInfo = new FileInfo( filePath );
            StreamReader sr = projectFileInfo.OpenText();
            while (sr.Peek() >= 0)
            {
                contents.Add(sr.ReadLine());
            }
            sr.Close();
 
        }
        public void AddKey(string key)
        {
                if(contents.Count < 2)
                        return;
                contents.Insert(contents.Count - 2,key);
 
        }
 
        public void ReplaceKey(string key,string replace){
            for(int i = 0;i < contents.Count;i++){
                    if(contents[i].IndexOf(key) != -1){
                            contents[i] = contents[i].Replace(key,replace);
                    }
            }
        }
 
        public void Save()
        {
            StreamWriter saveFile = File.CreateText(filePath);
            foreach(string line in contents)
                    saveFile.WriteLine(line);
            saveFile.Close();
        }
 
        public void Dispose()
        {
 
        }
    }
}

 ShareSDK在接入微信平台的时候 必须修改Unity生成的UnityAppController.mm 文件,这里我通过 XClass 自动修改UnityAppController.mm生成的代码。 主要是增加代码和替换代码 两部分。。

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

像这样,我就可以把unity生成的代码修改了。。

最后是工程地址:http://pan.baidu.com/s/1i3gLDTN

建议大家把工程下载下来看看一基本上就明白它的工作原理了。如果你掌握者本篇文章的知识 那么恭喜你 自动化打包就已经完成了一半。。 现在我们已经可以自动化生成 xcode工程了,等有时间的话我会把下一半shell 自动化打包.ipa的方法在整理出来。。

Unity3D研究院之IOS全自动编辑framework、plist、oc代码的更多相关文章

  1. Unity3D研究院之IOS全自动打包生成ipa

    接着上一篇文章, 自动生成framework,这篇文章我把shell自动化打包ipa整理了一下,希望大家喜欢,嘿嘿.. 建议大家先看一下上一篇文章.http://www.xuanyusong.com/ ...

  2. Unity3D研究院之IOS本地消息通知LocalNotification的使用(六十七)

    http://www.xuanyusong.com/archives/2632    现在的游戏里一般都会有本地消息,比如每天定时12点或者下午6点告诉玩家进入游戏领取体力.这种东西没必要服务器去推送 ...

  3. Unity3D研究院之IOS本地消息通知LocalNotification的使用

    原地址:http://www.xuanyusong.com/archives/2632   现在的游戏里一般都会有本地消息,比如每天定时12点或者下午6点告诉玩家进入游戏领取体力.这种东西没必要服务器 ...

  4. 【转载】Unity3D研究院之IOS自定义游戏摇杆与飞机平滑的移动

    移动开发游戏中使用到的触摸游戏摇杆在iPhone上是非常普遍的,毕竟是全触摸屏手机,今天MOMO 通过一个小例子和大家讨论Unity3D 中如何自定义一个漂亮的全触摸游戏摇杆.        值得高兴 ...

  5. 【转载】Unity3D研究院之IOS触摸屏手势控制镜头旋转与缩放

    前几篇文章介绍了很多Unity3D引擎自身的一些问题, 今天我们在回到IOS设备上讨论一些触摸屏幕手势,本章的目标是通过触摸iPhone屏幕手势 实现模型左右的旋转,与模型的缩放. 大家想一想模型的旋 ...

  6. 【转载】Unity3D研究院之IOS&Andoird使用Sharesdk遇到的坑

    这两天研究了一下ShareSDK,说实话挺好用的,但是还是有点坑的地方.那么雨松MOMO写下博文记录一下来我遇到的坑,嘿嘿. 大部分内容它的文档上已经说的很清楚了. http://wiki.share ...

  7. (转)Unity3D研究院之IOS&Android收集Log文件

    转自:http://www.xuanyusong.com/archives/2477 有段时间没有写过文章了,不知道大伙儿还记得雨松MOMO吗? 嘿嘿. 开发项目的时候尤其在处理与服务器交互这块,如果 ...

  8. Unity3D研究院之IOS Android支持中文与本地文件的读取写

       前几天有个朋友问我为什么在IOS平台中可以正常的读写文件可是在Android平台中就无法正常的读写.当时因为在上班所以我没时间来帮他解决,晚上回家后我就拿起安卓手机真机调试很快就定位问题所在,原 ...

  9. Unity3D研究院之IOS&Android收集Log文件(六十二)

    开发项目的时候尤其在处理与服务器交互这块,如果服务端程序看不到客户端请求的Log信息,那么无法修改BUG.在Windows上Unity会自动讲Log文件写入本地,但是在IOS和Android上确没有这 ...

随机推荐

  1. C# 将日期转换成中文格式

    没有什么难点,只是要小心,要考虑到月.日上 10 的说法,比如:10 不能直接转换成一〇,也不能像上 20 那样转换成一十〇,应该是十. 特点总结: 数字为 10 时,结果为十: 数字大于 10 时, ...

  2. floodfill算法解题示例

    Flood fill算法是从一个区域中提取若干个连通的点与其他相邻区域区分开(或分别染成不同颜色)的经典算法.因为其思路类似洪水从一个区域扩散到所有能到达的区域而得名.在GNU Go和扫雷中,Floo ...

  3. zedboard 驱动理解

    1 驱动程序的编写   驱动是LINUX开发的必经之路,应用层对底层的调用经过了库与内核,内核下面才是驱动层,当你在应用程序执行对底层的控制时,驱动程序为你的控制提供了接口,或者说是策略. #incl ...

  4. Android Audio Play Out Channel

    1: 7嘴8舌 扬声器, 耳机, 和听筒 就是通过: audiomanager.setmode(AudioManager.MODE_IN_COMMUNICATION)audiomanager.setS ...

  5. Java基础(二)

    下面来实现一个小程序,要求如下: 从键盘接收一个字符串,程序对其中所有的字符进行排序,例如键盘输入:helloitcast程序打印acehillostt 步骤分析: 1.键盘录入字符串,Scanner ...

  6. 七天学会NodeJS-学习笔记

    在网上发现一篇nodeJS教程,名为七天学会NodeJS,标题很有吸引力.我不指望七天能学会,只希望可以入门,下面是我的学习笔记和遇到的问题. 教程网址:http://nqdeng.github.io ...

  7. php判断是否为手机客户端

    function isWap() {        $http_agent = isset ( $_SERVER ["HTTP_USER_AGENT"] ) ? $_SERVER ...

  8. Golang container/ring闭环数据结构的使用方法

    //引入包 import "container/ring" //创建闭环,这里创建10个元素的闭环 r := ring.New(10) //给闭环中的元素附值 for i := 1 ...

  9. Android中表示尺寸的六种度量单位

    本文章来自:http://my.eoe.cn/lakeside/archive/4831.html in:Inches - 表示英寸,是屏幕的物理尺寸,每英寸等于2.54厘米.平时说手机屏幕4(英)寸 ...

  10. Redis 三:存储类型之字符串

    .赋值单个: [赋值多个:mset a b c ] .取值单个: get a [取值多个:mget a b c] .数字递增 incr a 在a的基础上+,那就是返回101 如果预先的值为0,那么返回 ...