工作中碰到由同一個項目,打包中不同包名的游戲apk或ipa的需求偶摔,比如項目Trunk1.0暇唾,需要打出一個包名為com.xx.xx.a的包,之后可能又需要打出包名為com.xx.xx.b的包辰斋。而每切換打新的包策州,就需要更改?
Product Name,Default Icon,Icon,BundleId,等等(如下圖 所示)?
所以為了更有效率打包亡呵,寫個編輯器一鍵設(shè)置這些參數(shù)勢在必行抽活。?
寫工具前先明白有哪些參數(shù)設(shè)置是包與包之前不同之處。?
這里針對我這個項目來介紹下:
主要改動的方面:
ProjectSetting
SDK相關(guān)
配置表的設(shè)計
通過將動態(tài)改變的參數(shù)放到配置表中?
這里我采取的是Excel來配置锰什,讀取using Excel;
`publicclassMenu{publicstringID ="";publicstringbundle_identifier ="";publicstringcompany_name ="";publicstringproduct_name ="";publicstringkeyaliasName ="";publicstringkeyaliasPass ="";publicstringkeystoreName ="";publicstringkeystorePass ="";publicstringWXAppID ="";publicstringscheme ="";}publicclassExcelAccess? {publicstaticstringExcelName ="ProjectSetting.xlsx";publicstaticstring[] SheetNames = {"Sheet1"};publicstaticListSelectMenuTable(inttableId,intappId)? ? {? ? ? ? DataRowCollection collect = ExcelAccess.ReadExcel(SheetNames[tableId -1]);? ? ? ? List menuArray =newList();for(inti =1; i < collect.Count; i++)? ? ? ? {if(i <3)continue;if(appId !=0)? ? ? ? ? ? {if(collect[i][0].ToString() != appId.ToString())continue;? ? ? ? ? ? }? ? ? ? ? ? Menu menu =newMenu();? ? ? ? ? ? menu.ID = collect[i][0].ToString();? ? ? ? ? ? menu.bundle_identifier = collect[i][1].ToString();? ? ? ? ? ? menu.company_name = collect[i][2].ToString();? ? ? ? ? ? menu.product_name = collect[i][3].ToString();? ? ? ? ? ? menu.keyaliasName = collect[i][4].ToString();? ? ? ? ? ? menu.keyaliasPass = collect[i][5].ToString();? ? ? ? ? ? menu.keystoreName = collect[i][6].ToString();? ? ? ? ? ? menu.keystorePass = collect[i][7].ToString();? ? ? ? ? ? menu.WXAppID = collect[i][8].ToString();? ? ? ? ? ? menu.scheme = collect[i][9].ToString();? ? ? ? ? ? menuArray.Add(menu);? ? ? ? }returnmenuArray;? ? }//////讀取 Excel 需要添加 Excel; System.Data;/////////staticDataRowCollection ReadExcel(stringsheet)? ? {? ? ? ? FileStream stream = File.Open(FilePath(ExcelName), FileMode.Open, FileAccess.Read, FileShare.Read);? ? ? ? IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);? ? ? ? DataSet result = excelReader.AsDataSet();returnresult.Tables[sheet].Rows;? ? }staticstringFilePath(stringname)? ? {stringpath = Application.dataPath +"/ExcelConfig/"+ name;returnpath;? ? }`
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
修改ProjectSetting
1.這里先介紹我們友好的編輯器界面:?
記錄選中的游戲是哪一款下硕,然后用一個唯一id記錄下來丁逝,當我點擊?設(shè)置?按鈕,把唯一id記錄在txt文件:
staticpublicvoidChangeAppId()? ? {? ? ? ? Debug.Log("--------------------------ChangeAppId--------------------------------------");if(menu !=null)? ? ? ? {stringpath = Application.dataPath +"/Resources/AppId.txt";? ? ? ? ? ? FileStream fs =newFileStream(path, FileMode.Create);? ? ? ? ? ? StreamWriter sw =newStreamWriter(fs);//開始寫入sw.Write(menu.ID);//清空緩沖區(qū)sw.Flush();//關(guān)閉流sw.Close();? ? ? ? ? ? fs.Close();? ? ? ? Debug.Log("【新的AppId】:"+ menu.ID);? ? ? ? }? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2.根據(jù)選中哪個游戲梭姓,對應動態(tài)修改ProjectSetting
menu為選中這款游戲在配置表里對應的數(shù)據(jù)?
數(shù)據(jù)的內(nèi)容格式:?
PlayerSettings.bundleIdentifier= menu.bundle_identifier;PlayerSettings.companyName= menu.company_name;PlayerSettings.productName= menu.product_name;PlayerSettings.defaultInterfaceOrientation= UIOrientation.LandscapeLeft;
1
2
3
4
Android和iOS在projectSetting設(shè)置有些區(qū)別(Android設(shè)置Device霜幼,打包的腳本,簽名誉尖,而ios沒有簽名這一項)?
Android上:
static public void SetAndroidProject(Menu menu)? ? {? ? ? ? if (isFormalPackage)? ? ? ? {? ? ? ? ? ? PlayerSettings.Android.targetDevice= AndroidTargetDevice.FAT;PlayerSettings.SetScriptingBackend(BuildTargetGroup.Android, ScriptingImplementation.IL2CPP);}? ? ? ? else? ? ? ? {? ? ? ? ? ? PlayerSettings.Android.targetDevice= AndroidTargetDevice.ARMv7;PlayerSettings.SetScriptingBackend(BuildTargetGroup.Android, ScriptingImplementation.Mono2x);}? ? ? ? PlayerSettings.Android.minSdkVersion= AndroidSdkVersions.AndroidApiLevel9;PlayerSettings.Android.keyaliasName= menu.keyaliasName;PlayerSettings.Android.keyaliasPass= menu.keyaliasPass;PlayerSettings.Android.keystoreName= menu.keystoreName;PlayerSettings.Android.keystorePass= menu.keystorePass;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
iOS上:
static public void SetIosProject(Menu menu)? ? {? ? ? ? PlayerSettings.iOS.targetDevice= iOSTargetDevice.iPhoneAndiPad;if (isFormalPackage)? ? ? ? {? ? ? ? ? ? PlayerSettings.SetScriptingBackend(BuildTargetGroup.iOS, ScriptingImplementation.IL2CPP);}? ? ? ? else? ? ? ? {? ? ? ? ? ? PlayerSettings.SetScriptingBackend(BuildTargetGroup.iOS, ScriptingImplementation.Mono2x);}? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
3.icon方面的動態(tài)更改?
1:ICON?
這里放置美術(shù)給的app的icon?
Android:?
iOS上:?
2:LoginImage 對應的圖片是default?
icon罪既,圖片都是從ICON文件夾里Android:256,iOS:180尺寸拷貝過來的铡恕。
publicstaticvoidGenerateLoginImage(RuntimePlatform platform)? ? {if(menu !=null)? ? ? ? {intappId =int.Parse(menu.ID);//D:\trunk1.0\BackUp\Plugins_Android\1 目錄創(chuàng)建stringrootPath = Application.dataPath +"/BackUp/LoginImage/"+ appId;? ? ? ? ? ? rootPath = rootPath.Replace("Assets/","");? ? ? ? ? ? DirectoryInfo rootDirec =null;if(File.Exists(rootPath) ==false)//創(chuàng)建根目錄{? ? ? ? ? ? ? ? rootDirec = Directory.CreateDirectory(rootPath);? ? ? ? ? ? }else{? ? ? ? ? ? ? ? rootDirec =newDirectoryInfo(rootPath);? ? ? ? ? ? }? ? ? ? ? ? Debug.Log("【LoginImage】:"+ rootPath);stringplatformName = platform == RuntimePlatform.Android ?"Android":"IOS";stringiconSizePic = platform == RuntimePlatform.Android ?"256.png":"180.png";stringicon_srcPath = Application.dataPath +"/BackUp/ICON/"+ appId +"/"+ platformName +"/"+ iconSizePic;? ? ? ? ? ? icon_srcPath = icon_srcPath.Replace("Assets/","");stringicon_animPath = Application.dataPath +"/BackUp/LoginImage/"+ appId+"/Icon.png";? ? ? ? ? ? icon_animPath = icon_animPath.Replace("Assets/","");? ? ? ? ? ? CopyAndReplace(icon_srcPath, icon_animPath);//app icon}? ? }privatestaticvoidCopyAndReplace(stringsrcPath,stringanimPath)? ? {? ? ? ? Debug.Log("從目錄:"+ srcPath);? ? ? ? Debug.Log("拷貝到:"+ animPath);? ? ? ? File.Copy(srcPath, animPath,true);? ? }
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
3:Share_Image?
微信分享圖片:圖片按照你自己放置的路徑來定?
4:Plugins_Android?
(稍后講)
我們項目工程已經(jīng)存在了icon引用了Assets下的某張圖片琢感,?
當需要改動這些圖片的時候,只需要將目標圖片拷貝過來替換掉就可以探熔。
staticpublicvoidReplaceIcon(intappId, RuntimePlatform platform)? ? {stringplatformName = platform == RuntimePlatform.Android ?"Android":"IOS";stringscrPath = Application.dataPath +"/BackUp/ICON/"+ appId +"/"+ platformName;? ? ? ? scrPath = scrPath.Replace("Assets/","");stringaminPath = Application.dataPath +"/Art/ICON/"+ platformName;? ? ? ? Debug.Log("--------------------------ReplaceIcon--------------------------------------");? ? ? ? Debug.Log("【ReplaceIcon scrPath】="+ scrPath);? ? ? ? Debug.Log("【ReplaceIcon aminPath】="+ aminPath);? ? ? ? FileUtils.CopyDir(scrPath, aminPath);? ? }
1
2
3
4
5
6
7
8
9
10
11
12
so easy,就是簡單的文件或文件夾拷貝
SDK相關(guān)
我們游戲接的是微信SDK驹针,這里只講微信SDK相關(guān)
觀察這個Plugins下的目錄?
bin文件夾放置jar包?
res:icon之類?
AndroidManifest.xml:項目的權(quán)限配置等
jar包?
需要更改包名?
如圖所示:直接手動更改,導出csmj.jar?
微信appid是動態(tài)改變的诀艰,所以把appid抽出到配置AndroidManifest.xml?
然后代碼里動態(tài)獲得:
publicStringgetWXAppId()? ? {? ? ? ? ApplicationInfo appInfo;? ? ? ? String WXAppId ="";try{? ? ? ? ? ? PackageManager pm =this.getPackageManager();if(pm !=null)? ? ? ? ? ? {? ? ? ? ? ? ? ? appInfo = pm.getApplicationInfo(this.getPackageName(), PackageManager.GET_META_DATA);? ? ? ? ? ? ? ? WXAppId =appInfo.metaData.getString("WXAppId");? ? ? ? ? ? ? ? Log.i("Unity","WXAppId="+WXAppId);? ? ? ? ? ? }? ? ? ? ? }catch(NameNotFoundException e)? ? ? ? {? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? Log.d("Unity", e.getMessage());? ? ? ? }returnWXAppId;? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
res:
從ICON對應拷貝
//修改Plugins/Android/RespublicstaticvoidRefreshResFolder()? ? {if(menu !=null)? ? ? ? {intappId =int.Parse(menu.ID);//D:\trunk1.0\BackUp\Plugins_Android\1 目錄創(chuàng)建stringrootPath = Application.dataPath +"/BackUp/Plugins_Android/"+ appId;? ? ? ? ? ? rootPath = rootPath.Replace("Assets/","");? ? ? ? ? ? DirectoryInfo rootDirec =null;if(File.Exists(rootPath) ==false)//創(chuàng)建根目錄{? ? ? ? ? ? ? ? rootDirec = Directory.CreateDirectory(rootPath);? ? ? ? ? ? }else{? ? ? ? ? ? ? ? rootDirec =newDirectoryInfo(rootPath);? ? ? ? ? ? }? ? ? ? ? ? Debug.Log("目標根目錄:"+ rootPath);//D:\trunk1.0\BackUp\Plugins_Android\0 將模板目錄下的res文件夾拷貝到目標目錄下stringtemplateSrcPath = Application.dataPath +"/BackUp/Plugins_Android/0";? ? ? ? ? ? templateSrcPath = templateSrcPath.Replace("Assets/","");? ? ? ? ? ? FileUtils.CopyDir(templateSrcPath, rootPath);//把0目錄下的內(nèi)容拷貝到目標目錄string[] folders =newstring[] {"drawable","drawable-hdpi","drawable-ldpi","drawable-mdpi","drawable-xhdpi","drawable-xxhdpi","drawable-xxxhdpi"};string[] icons =newstring[] {"96","72","36","48","96","144","192"};string[] newName_icons =newstring[] {"icon","app_icon","app_icon","app_icon","app_icon","app_icon","app_icon"};intfolderLen = folders.Length;for(intfolderIndex =0; folderIndex < folderLen; folderIndex++)? ? ? ? ? ? {stringplatformName ="Android";stringicon_srcPath = Application.dataPath +"/BackUp/ICON/"+ appId +"/"+ platformName+"/"+icons[folderIndex]+".png";//D:\trunk1.0\Assets\BackUp\ICON\9\Android\96.pngicon_srcPath = icon_srcPath.Replace("Assets/","");stringicon_animPath = rootPath +"/res/"+ folders[folderIndex]+"/"+ newName_icons[folderIndex] +".png";? ? ? ? ? ? ? ? CopyAndReplace(icon_srcPath, icon_animPath);? ? ? ? ? ? }? ? ? ? }? ? }
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
AndroidManifest.xml?
修改要點:替換成新包名柬甥,wxappid替換,urlscheme替換
static public void ChangeAndroidXml(int appId, Menu menu)? ? {? ? ? ? Debug.Log("--------------------------ChangeAndroidXml--------------------------------------");string xmlPath = Application.dataPath+"/Plugins/Android/AndroidManifest.xml";XmlDocument xmlDoc = new XmlDocument();XmlReaderSettingsset= new XmlReaderSettings();set.IgnoreComments= true;//這個設(shè)置是忽略xml注釋文檔的影響其垄。有時候注釋會影響到xml的讀取XmlReader reader = XmlReader.Create(xmlPath,set);xmlDoc.Load(reader);reader.Close();//最后讀取完畢后,記得要關(guān)掉reader.//獲取bookshop節(jié)點的所有子節(jié)點? ? ? ? XmlNodeList node = xmlDoc.GetElementsByTagName("manifest");string oldPackageName ="";foreach (XmlElement ninnode)? ? ? ? {? ? ? ? ? ? if (n.Name=="manifest")? ? ? ? ? ? {? ? ? ? ? ? ? ? string package = n.Attributes["package"].Value;if (package !="")? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? Debug.Log("【 舊包名】:"+ package);oldPackageName = package;n.SetAttribute("package", menu.bundle_identifier);}break;}? ? ? ? }? ? ? ? XmlNodeList nodeList = xmlDoc.SelectSingleNode("manifest").ChildNodes;foreach (XmlElement xninnodeList)? ? ? ? {? ? ? ? ? ? //Debug.Log("name ="+ xn.Name);if (xn.Name=="application")? ? ? ? ? ? {? ? ? ? ? ? ? ? XmlNodeList target = xn.ChildNodes;foreach (XmlElement xxintarget)? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? if (xx.Name=="meta-data")//替換微信APPID? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ChangeWXAppId(menu, xx);}? ? ? ? ? ? ? ? ? ? else if (xx.Name=="activity")//替換APP的scheme? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ChangeAppScheme(menu, xx);if (oldPackageName !="")? ? ? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? XmlAttributeCollection attributeCollection = xx.Attributes;foreach (XmlAttribute attrinattributeCollection)? ? ? ? ? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //Debug.Log("attr attr.Name"+ attr.Name+"---attr.Value="+ attr.Value);if (attr.Value.Contains(oldPackageName))? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //替換掉舊包名? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? string value = attr.Value.Replace(oldPackageName, menu.bundle_identifier);xx.SetAttribute(attr.Name, value);}? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? ? ? xmlDoc.Save(xmlPath);Debug.Log("-----------------------修改 Androidmanifest OK---------------------------");}? ? private static void ChangeAppScheme(Menu menu, XmlElement ele)? ? {? ? ? ? Debug.Log("------------------------------------ChangeAppScheme------------------------------");XmlNodeList activityNodes = ele.ChildNodes;foreach (XmlElement xmlNodeinactivityNodes)? ? ? ? {? ? ? ? ? ? if (xmlNode.Name=="intent-filter")? ? ? ? ? ? {? ? ? ? ? ? ? ? XmlNodeList intentNodes = xmlNode.ChildNodes;foreach (XmlElement nodeinintentNodes)? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? //? ? ? ? ? ? ? ? ? ? ? if (node.Name=="data")? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? if(node.GetAttribute("android:scheme") !="")? ? ? ? ? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? node.SetAttribute("android:scheme", menu.scheme);Debug.Log("【App scheme】:"+ menu.scheme);return;}? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }? ? private static void ChangeWXAppId(Menu menu, XmlElement ele)? ? {? ? ? ? ? ? Debug.Log("------------------------------------替換微信APPID------------------------------");//? ? ? ? ? ? if (ele.GetAttribute("android:name") =="WXAppId")? ? ? ? {? ? ? ? ? ? ele.SetAttribute("android:value", menu.WXAppID);Debug.Log("【微信APPID 】="+ menu.WXAppID);}? ? }
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
104
105
106
107
108
109
110
111
112
113
至此苛蒲,Android的修改已經(jīng)完成。
using System.Collections;using System.Collections.Generic;using System.IO;using UnityEditor;using UnityEditor.Callbacks;#if UNITY_IPHONEusing UnityEditor.iOS.Xcode;#endifusing UnityEngine;#if UNITY_IPHONEpublic class XcodeSetting : MonoBehaviour{? ? private static List menuList;[PostProcessBuild(999)]? ? public static void OnPostprocessBuild(BuildTarget BuildTarget, string path)? ? {? ? ? ? if (BuildTarget == BuildTarget.iOS)? ? ? ? {? ? ? ? ? ? Debug.Log(path);string projPath = PBXProject.GetPBXProjectPath(path);PBXProject proj = new PBXProject();proj.ReadFromString(File.ReadAllText(projPath));string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName());proj.SetBuildProperty(target,"ENABLE_BITCODE","NO");//C#讀取TXT文件之建立? FileStream 的對象,說白了告訴程序,? ? //文件在那里,對文件如何 處理,對文件內(nèi)容采取的處理方式? ? ? ? ? ? ? ? string txtPath = Application.dataPath+"/Resources/AppId.txt";FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs);//僅 對文本 執(zhí)行? 讀寫操作 int AppId = int.Parse(sr.ReadToEnd());//C#讀取TXT文件之關(guān)上文件绿满,留心順序臂外,先對文件內(nèi)部執(zhí)行 關(guān)上,然后才是文件~? ? sr.Close();fs.Close();menuList = ExcelAccess.SelectMenuTable(1, AppId);if (menuList != null)? ? ? ? ? ? {? ? ? ? ? ? ? ? if (menuList.Count>0)? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? Menu menu = menuList[0];string wxAppid = menu.WXAppID;//UrlType? ? ? ? ? ? ? ? ? ? //Handle plist? ? ? ? ? ? ? ? ? ? ? string plistPath = path +"/Info.plist";PlistDocument plist = new PlistDocument();plist.ReadFromString(File.ReadAllText(plistPath));PlistElementDict rootDict = plist.root;rootDict.SetString("NSLocationAlwaysUsageDescription","地理位置ios8后");rootDict.SetString("NSLocationUsageDescription","iOS8之前向用戶申請位置信息獲取授權(quán)");rootDict.SetString("NSLocationWhenInUseUsageDescription","地理位置iOS8后");rootDict.SetString("NSMicrophoneUsageDescription","使用麥克風");rootDict.SetString("NSPhotoLibraryUsageDescription","使用相冊");PlistElementArray urlTypes = rootDict.CreateArray("CFBundleURLTypes");//addweixin url scheme? ? ? ? ? ? ? ? ? ? PlistElementDict wxUrl = urlTypes.AddDict();wxUrl.SetString("CFBundleTypeRole","Editor");wxUrl.SetString("CFBundleURLName","weixin");PlistElementArray wxUrlScheme = wxUrl.CreateArray("CFBundleURLSchemes");wxUrlScheme.AddString(wxAppid);//addcsmj url scheme? ? ? ? ? ? ? ? ? ? PlistElementDict appUrl = urlTypes.AddDict();appUrl.SetString("CFBundleTypeRole","Editor");appUrl.SetString("CFBundleURLName","chaoshanmajiang");PlistElementArray appUrlScheme = appUrl.CreateArray("CFBundleURLSchemes");appUrlScheme.AddString(menu.scheme);File.WriteAllText(plistPath, plist.WriteToString());}? ? ? ? ? ? }? ? }}}#endif
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
iOS修改xcode工程棒口,需要在打包完畢后寄月,會自動調(diào)用?
[PostProcessBuild(999)]?
public static void OnPostprocessBuild(BuildTarget BuildTarget, string path)
如果代碼報錯,請在playersetting里 下載ios相關(guān)无牵。
其他設(shè)置等我以后解鎖再添加漾肮。Mark一下。
2017-08-07更新?
PS:新增替換外部圖片?
using System.Collections;?
using System.Collections.Generic;?
using System.IO;?
using UnityEditor;?
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;
public class XcodeSetting : MonoBehaviour?
{?
private static List
menuList;
[PostProcessBuild(999)]
public static void OnPostprocessBuild(BuildTarget BuildTarget, string path)
{
? ? if (BuildTarget == BuildTarget.iOS)
? ? {
? ? ? ? Debug.Log("OnPostprocessBuild ProjectPath:" + path);
? ? ? ? string projPath = PBXProject.GetPBXProjectPath(path);//獲取.xcodeproj文件的路徑
? ? ? ? PBXProject proj = new PBXProject();//new()一個PBXProject對象茎毁,然后從上面獲取的路徑中讀出字符串克懊。
? ? ? ? string contents = File.ReadAllText(projPath);
? ? ? ? proj.ReadFromString(contents);
? ? ? ? string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName());//獲取targetGUID
? ? ? ? // 鏈接器
? ? ? ? proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");//bitcode是被編譯程序的一種中間形式的代碼。包含bitcode配置的程序?qū)贏pp store上被編譯和鏈接七蜘。bitcode允許蘋果在后期重新優(yōu)化我們程序的二進制文件(我們第三方庫不一定支持谭溉,所以要設(shè)置為NO)
? ? ? ? proj.SetBuildProperty (target, "OTHER_LDFLAGS", "-Objc -all_load -lstdc++.6.0.9 -lsqlite3");//Other Linker Flags? 在ios開發(fā)過程中,有時候會用到第三方的靜態(tài)庫(.a文件)橡卤,然后導入后發(fā)現(xiàn)編譯正常但運行時會出現(xiàn)selector not recognized的錯誤扮念,從而導致app閃退。
? ? ? ? //pbxProj.AddBuildProperty(targetGuid, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");
? ? ? ? //pbxProj.AddBuildProperty(targetGuid, "HEADER_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");
? ? ? ? //pbxProj.AddBuildProperty(targetGuid, "LIBRARY_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");
? ? ? ? //------------------------拷貝系統(tǒng)Framework----------------------------------------------
? ? ? ? string xcodePath = Application.dataPath + "/xcode.txt";
? ? ? ? xcodePath = xcodePath.Replace("Assets/", "");
? ? ? ? FileStream xcode_fs = new FileStream(xcodePath, FileMode.Open, FileAccess.Read);
? ? ? ? StreamReader xcode_sr = new StreamReader(xcode_fs);//僅 對文本 執(zhí)行? 讀寫操作
? ? ? ? string line = null;
? ? ? ? while((line= xcode_sr.ReadLine())!= null)
? ? ? ? {
? ? ? ? ? ? Debug.Log ("framework=" + line);
? ? ? ? ? ? string frameWorkName = line.Split('.')[0];
? ? ? ? ? ? string filterName = line.Split ('.') [1];
? ? ? ? ? ? if (filterName == "framework") {
? ? ? ? ? ? ? ? if(frameWorkName == "JavaScriptCore")
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? proj.AddFrameworkToProject(target, line, true);//這里第一個參數(shù)是第三部中獲取到的GUID碧库,第二個參數(shù)是framework名(這里一定要是.framework為后綴)柜与,第三個參數(shù)是用來設(shè)置framework是require還是optional巧勤。
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? proj.AddFrameworkToProject(target, line, false);//這里第一個參數(shù)是第三部中獲取到的GUID,第二個參數(shù)是framework名(這里一定要是.framework為后綴)弄匕,第三個參數(shù)是用來設(shè)置framework是require還是optional颅悉。
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? proj.AddFileToBuild (target, proj.AddFile("usr/lib/"+line, "Frameworks/"+line, PBXSourceTree.Sdk));
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //C#讀取TXT文件之關(guān)上文件,留心順序迁匠,先對文件內(nèi)部執(zhí)行 關(guān)上剩瓶,然后才是文件~? ?
? ? ? ? xcode_sr.Close();
? ? ? ? xcode_fs.Close();
? ? ? ? //--------------------------拷貝系統(tǒng)Framework end-------------------------------------
? ? ? ? File.WriteAllText(projPath, proj.WriteToString());
? ? ? ? //------------------------------APPID-----------------------------------------------------
? ? ? ? string txtPath = Application.dataPath + "/Resources/AppId.txt";
? ? ? ? FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read);
? ? ? ? StreamReader sr = new StreamReader(fs);//僅 對文本 執(zhí)行? 讀寫操作
? ? ? ? int AppId = int.Parse(sr.ReadToEnd());
? ? ? ? //C#讀取TXT文件之關(guān)上文件,留心順序城丧,先對文件內(nèi)部執(zhí)行 關(guān)上延曙,然后才是文件~? ?
? ? ? ? sr.Close();
? ? ? ? fs.Close();
? ? ? ? menuList = ExcelAccess.SelectMenuTable(1, AppId);
? ? ? ? if (menuList != null)
? ? ? ? {
? ? ? ? ? ? if (menuList.Count > 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Menu menu = menuList[0];
? ? ? ? ? ? ? ? string wxAppid = menu.WXAppID;
? ? ? ? ? ? ? ? PlistElementDict dict;
? ? ? ? ? ? ? ? //UrlType
? ? ? ? ? ? ? ? //Handle plist?
? ? ? ? ? ? ? ? string plistPath = path + "/Info.plist";
? ? ? ? ? ? ? ? PlistDocument plist = new PlistDocument();
? ? ? ? ? ? ? ? plist.ReadFromString(File.ReadAllText(plistPath));
? ? ? ? ? ? ? ? PlistElementDict rootDict = plist.root;
? ? ? ? ? ? ? ? //NSContactsUsageDescription->通訊錄
? ? ? ? ? ? ? ? //NSMicrophoneUsageDescription->麥克風
? ? ? ? ? ? ? ? //NSPhotoLibraryUsageDescription->相冊
? ? ? ? ? ? ? ? //NSCameraUsageDescription->相機
? ? ? ? ? ? ? ? //NSLocationAlwaysUsageDescription->地理位置
? ? ? ? ? ? ? ? //NSLocationWhenInUseUsageDescription->地理位置
? ? ? ? ? ? ? ? rootDict.SetString("NSLocationAlwaysUsageDescription", "地理位置相近的玩家不可進入同一個牌桌");
? ? ? ? ? ? ? ? rootDict.SetString("NSLocationUsageDescription", "地理位置相近的玩家不可進入同一個牌桌");
? ? ? ? ? ? ? ? rootDict.SetString("NSLocationWhenInUseUsageDescription", "地理位置相近的玩家不可進入同一個牌桌");
? ? ? ? ? ? ? ? rootDict.SetString("NSMicrophoneUsageDescription", "使用麥克風");
? ? ? ? ? ? ? ? rootDict.SetString("NSPhotoLibraryUsageDescription", "使用相冊");
? ? ? ? ? ? ? ? //PList文件添加微信為白名單
? ? ? ? ? ? ? ? PlistElementArray array = rootDict.CreateArray("LSApplicationQueriesSchemes");
? ? ? ? ? ? ? ? array.AddString("weixin");
? ? ? ? ? ? ? ? // 設(shè)置支持HTTP
? ? ? ? ? ? ? ? dict = rootDict.CreateDict("NSAppTransportSecurity");
? ? ? ? ? ? ? ? dict.SetBoolean("NSAllowsArbitraryLoads", true);
? ? ? ? ? ? ? ? PlistElementArray urlTypes = rootDict.CreateArray("CFBundleURLTypes");
? ? ? ? ? ? ? ? // add weixin url scheme應用需要在“Info.plist”中將要使用的URL Schemes列為白名單,才可正常檢查其他應用是否安裝芙贫。
? ? ? ? ? ? ? ? PlistElementDict wxUrl = urlTypes.AddDict();
? ? ? ? ? ? ? ? wxUrl.SetString("CFBundleTypeRole", "Editor");
? ? ? ? ? ? ? ? wxUrl.SetString("CFBundleURLName", "weixin");
? ? ? ? ? ? ? ? PlistElementArray wxUrlScheme = wxUrl.CreateArray("CFBundleURLSchemes");
? ? ? ? ? ? ? ? wxUrlScheme.AddString(wxAppid);
? ? ? ? ? ? ? ? //add csmj url scheme
? ? ? ? ? ? ? ? PlistElementDict appUrl = urlTypes.AddDict();
? ? ? ? ? ? ? ? appUrl.SetString("CFBundleTypeRole", "Editor");
? ? ? ? ? ? ? ? appUrl.SetString("CFBundleURLName", "chaoshanmajiang");
? ? ? ? ? ? ? ? PlistElementArray appUrlScheme = appUrl.CreateArray("CFBundleURLSchemes");
? ? ? ? ? ? ? ? appUrlScheme.AddString(menu.scheme);
? ? ? ? ? ? ? ? //add location appkey url scheme
? ? ? ? ? ? ? ? PlistElementDict locationUrl = urlTypes.AddDict();
? ? ? ? ? ? ? ? locationUrl.SetString("CFBundleTypeRole", "Editor");
? ? ? ? ? ? ? ? locationUrl.SetString("CFBundleURLName", "locationAppKey");
? ? ? ? ? ? ? ? PlistElementArray locationScheme = locationUrl.CreateArray("CFBundleURLSchemes");
? ? ? ? ? ? ? ? locationScheme.AddString("xx"+menu.Location_AppKey);
? ? ? ? ? ? ? ? File.WriteAllText(plistPath, plist.WriteToString());
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? CopyAndReplaceIcon (path);
? ? }
}
static void CopyAndReplaceIcon (string projectPath)
{
? ? string targetWXShareIconPath = projectPath + "/SDK/WX/res2.png";
? ? string sourceIconPath = System.Environment.CurrentDirectory + "/Assets/Art/ICON/IOS/57.png";
? ? Debug.Log (string.Format ("CopyAndReplaceIcon from {0} to {1}", sourceIconPath, targetWXShareIconPath));
? ? File.Copy (sourceIconPath, targetWXShareIconPath, true);
}
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
}