对Unity3D的iOS导出插件XUPorter的plist处理功能的改进

XUPorter

是一个可以在U3D生成iOS所需Xcode项目时自动完成一些如添加framework,修改编译参数等操作的Editor插件。这个插件对于同一个项目需要接入各种不同渠道的SDK生成对应IPA的需求可以很方便快捷的实现自动化操作,降低项目维护复杂度。
在使用这个插件时,发现了些小问题,查看作者声明时发现其已经不在对这个插件进行维护了,于是只好自己动手做一些修改完善:
本文记录的就是对plist的处理功能,原代码逻辑中XCProject.cs中的ApplyMod函数会根据.projmods的信息对Xcode项目文件进行一系列的修改,其中一部是对项目.plist的修改,但这一步用我当时取到的github最新版本时会出错,仔细检查了下,发现无论projmods中的plist段写不写,生成对应的XCMod对象的plist总会是null,检查了下这个json数据解析生成类,发现plist的类型是“Hashtable”,而不像其他一些字段,如group是string,libs是ArrayList等,改换了下projmods中的json写法,又发现虽然可以解析成功不为null了,但实际修改plist逻辑又出现了问题,原逻辑是通过XCPlist的Process函数对projmods中提供的信息项对原项目plist进行合并修改,但是代码中对各种plist选项的处理不并完善,只有一个特殊if:

		public void AddPlistItems(string key, object value, Dictionary<string, object> dict)
		{
			Debug.Log ("AddPlistItems: key=" + key);
			
			if (key.CompareTo(PlistUrlType) == 0)
			{
				processUrlTypes((ArrayList)value, dict);
			}
			else
			{
				dict[key] = HashtableToDictionary<string, object>((Hashtable)value);
				plistModified = true;
			}
		}

会对URLSchemes做处理,显然这样无法实现通用的plist修改逻辑,思考过后我决定将其实现改为读取指定plist文件中的key项并与项目plist进行合并,覆盖已有的项,添加没有的项,具体实现如下:

首先,修改XCMod中plist属性的类型

		/*
		public Hashtable plist {
			get {
				return (Hashtable)_datastore["plist"];
			}
		}
		*/
		public string plist {
			get {
				if (_datastore != null && _datastore.Contains("plist"))
					return (string)_datastore["plist"];
				return string.Empty;
			}
		}

这里我修改为了单string参数,如果有需要的话也可以改为ArrayList数组处理多个plist。然后,修改XCPlist类,加入如下合并处理函数

		public void Merge(XCPlist plist)
		{
			Dictionary<string, object> dict = (Dictionary<string, object>)PlistCS.Plist.readPlist(plistPath);
			Dictionary<string, object> dictMerge = (Dictionary<string, object>)PlistCS.Plist.readPlist(plist.plistPath);

			foreach (KeyValuePair<string, object> pair in dictMerge)
			{
				dict[pair.Key] = pair.Value;
				plistModified = true;
			}

			if (plistModified)
			{
				PlistCS.Plist.writeXml(dict, plistPath);
			}
		}

此函数实现合并plist中key及覆写值的功能。最后,修改XCProject类的”Adding plist items…”一步

//			Debug.Log ("Adding plist items...");
			Debug.Log ("Merging plist items...");
			if (!string.IsNullOrEmpty(mod.plist)) {
				string plistPath = this.projectRootPath + "/Info.plist";
				XCPlist plist = new XCPlist (plistPath);
				XCPlist mergePlist = new XCPlist(System.IO.Path.Combine( mod.path, mod.plist ));
				plist.Merge(mergePlist);
//				plist.Process (mod.plist);
			}

使用Merge进行操作。参考如下合并plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>zh_CN</string>
	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>CFBundleURLName</key>
			<string>com.ky.xSDK.alipay</string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>com.unity.myapp</string>
			</array>
		</dict>
	</array>
	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>alipay</string>
		<string>weixin</string>
		<string>mqqapiwallet</string>
	</array>
	<key>UIRequiresFullScreen</key>
	<true/>
	<key>Unity_LoadingActivityIndicatorStyle</key>
	<integer>-1</integer>
</dict>
</plist>

生成Xcode项目时,.projmods中的plist项指定此plist路径,插件会自动将此plist中的key项合并到生成项目的plist中,自动完成一些项目信息配置的修改。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。