Unity 自5以后自带了IOS的XCode 配置导出功能,目前网络上对这个功能的资料不多,我们正在进行的项目又需要能自动导出XCode 配置,之前使用的XUPorter,但是由于作者已经不再更新,而且Bug挺多,现在切换到Unity自带的。 先来看下代码:…
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode; //引入xcode 库,需要Unity 安装IOS的支持
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
public class XcodeProjectMod : Editor
{
private static string projectPath = "/xxx/"; //存放需要导入的库,framework等文件的目录
//文件复制,去除掉.meta文件,.ds_store文件
internal static void CopyAndReplaceDirectory(string srcPath, string dstPath)
{
if (Directory.Exists(dstPath))
Directory.Delete(dstPath);
if (File.Exists(dstPath))
File.Delete(dstPath);
Directory.CreateDirectory(dstPath);
foreach (var file in Directory.GetFiles(srcPath)) {
if (!file.EndsWith (".meta") && !file.EndsWith (".DS_Store")) {
File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)));
}
}
foreach (var dir in Directory.GetDirectories(srcPath))
CopyAndReplaceDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)));
}
//文件列表
struct dirPath
{
public string path;
public string sourcePath;
}
private static List<dirPath> PathList = new List<dirPath>();
//将库文件添加到列表中
internal static void AddFilesBuild(string path,string sourcePath,string parentPath,string dirname="")
{
if (Directory.Exists (parentPath+path+"/"+dirname)) {
DirectoryInfo di = new DirectoryInfo (parentPath + path+"/" + dirname);
foreach (FileInfo fi in di.GetFiles())
{
if (!fi.Name.EndsWith (".DS_Store")) {
dirPath p = new dirPath();
p.path = path + "/" + dirname + fi.Name;
p.sourcePath = sourcePath + "/" + dirname + fi.Name;
PathList.Add (p);
}
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
if (dir.Name.EndsWith (".framework"))
{
dirPath p = new dirPath();
p.path = path+"/" + dirname+ dir.Name;
p.sourcePath = "Frameworks/" + dirname+ dir.Name;
PathList.Add (p);
}
else if(dir.Name.EndsWith (".bundle"))
{
dirPath p = new dirPath();
p.path = path+"/" + dirname+ dir.Name;
p.sourcePath = sourcePath +"/" + dirname+ dir.Name;
PathList.Add (p);
}
else
{
AddFilesBuild (path, sourcePath,parentPath, dirname + dir.Name+"/");
}
}
}
}
//注入到导出过程
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
//获取项目目录,配置表,TargetGuidByName填写自己的target
string projPath = PBXProject.GetPBXProjectPath(path);
PBXProject proj = new PBXProject();
proj.ReadFromString(File.ReadAllText(projPath));
string target = proj.TargetGuidByName("Unity-iPhone");
// add framework
proj.AddFrameworkToProject(target, "StoreKit.framework", false);
//add lib
//PBXSourceTree.Sdk sdk目录
proj.AddFileToBuild(target, proj.AddFile("usr/lib/libc++.tbd", "Libraries/libc++.tbd", PBXSourceTree.Sdk));
CopyAndReplaceDirectory (Application.dataPath + projectPath + "/lib", path + "/lib");
PathList.Clear();
AddFilesBuild ("lib", "lib", path + "/");
for (int i = 0; i < PathList.Count; i++) {
if(PathList[i].path.EndsWith("yyy.m"))
{
//需要参数编译的文件
proj.AddFileToBuildWithFlags(target, proj.AddFile(PathList[i].path, PathList[i].sourcePath, PBXSourceTree.Source),"-fno-objc-arc");
}
else{
proj.AddFileToBuild(target, proj.AddFile(PathList[i].path, PathList[i].sourcePath, PBXSourceTree.Source));
}
}
//set sign property
//签名的profile
proj.SetBuildProperty (target, "PROVISIONING_PROFILE_SPECIFIER", "ms_adhoc_20170208");
//签名证书(最好先在xcode手动配置成功后,阅读project.pbxproj文件获取正确配置)
proj.SetBuildProperty (target, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Distribution: Mei peng (49MCUG4F6Q)");
proj.SetBuildProperty (target, "CODE_SIGN_IDENTITY", "iPhone Distribution: Mei peng (49MCUG4F6Q)");
proj.SetBuildProperty (target, "DEVELOPMENT_TEAM", "49MCUG4F6Q");
proj.SetBuildProperty (target, "PRODUCT_NAME", "ios");
//set property
//设置编译参数
proj.AddBuildProperty (target, "OTHER_LDFLAGS", "-ObjC");
//设置目标系统
proj.SetBuildProperty (target, "IPHONEOS_DEPLOYMENT_TARGET", "7.0");
//设置framework目录
proj.SetBuildProperty (target, "FRAMEWORK_SEARCH_PATHS", "$(inherited)");
proj.AddBuildProperty (target, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks");
//设置bitcode 一般为NO
proj.SetBuildProperty (target, "ENABLE_BITCODE", "NO");
//添加framework目录。这是添加
proj.AddBuildProperty (target, "FRAMEWORK_SEARCH_PATHS", Application.dataPath + projectPath + "/xxx");
//添加headr目录。这是添加
proj.AddBuildProperty (target, "HEADER_SEARCH_PATHS", Application.dataPath + projectPath + "/xxx");
//添加library目录。这是添加
proj.AddBuildProperty (target, "LIBRARY_SEARCH_PATHS", Application.dataPath + projectPath + "/xxx");
//开始写入配置文件
File.WriteAllText(projPath, proj.WriteToString());
//set plist
//开始info.plist
//plist文件目录
string _plistPath = path + "/Info.plist";
PlistDocument _plist = new PlistDocument ();
_plist.ReadFromString (File.ReadAllText (_plistPath));
PlistElementDict _rootDic = _plist.root;
//对应 <key>abc</key><string>abc</string>
_rootDic.SetString ("abc", "abc");
//创建array 对应
//<key>CFBundleURLTypes</key>
//<array>
//<dict>
// <key>CFBundleTypeRole</key>
// <string>Editor</string>
// <array>
// <key>CFBundleURLSchemes</key>
// <string>fb1687842111242336</string>
// </array>
// <key>CFBundleTypeRole</key>
// <string>Editor</string>
// <array>
// <key>CFBundleURLSchemes</key>
// <string>gm99mstwlink</string>
// </array>
//</dict>
//</array>
PlistElementArray CFBundleURLTypes =_rootDic.CreateArray("CFBundleURLTypes");
PlistElementDict CFBundleURLTypes1 = CFBundleURLTypes.AddDict();
CFBundleURLTypes1.SetString ("CFBundleTypeRole", "Editor");
PlistElementArray CFBundleURLSchemes1 = CFBundleURLTypes1.CreateArray ("CFBundleURLSchemes");
CFBundleURLSchemes1.AddString ("321");
PlistElementDict CFBundleURLTypes2 = CFBundleURLTypes.AddDict();
CFBundleURLTypes2.SetString ("CFBundleTypeRole", "Editor");
PlistElementArray CFBundleURLSchemes2 = CFBundleURLTypes2.CreateArray ("CFBundleURLSchemes");
CFBundleURLSchemes2.AddString ("123");
PlistElementArray UIBackgroundModes =_rootDic.CreateArray("UIBackgroundModes");
UIBackgroundModes.AddString ("fetch");
UIBackgroundModes.AddString ("remote-notification");
_rootDic.SetBoolean ("UIRequiresFullScreen", true);
_rootDic.values.Remove ("NSLocationWhenInUseUsageDescription");
PlistElementDict NSAppTransportSecurity = _rootDic.CreateDict ("NSAppTransportSecurity");
NSAppTransportSecurity.SetBoolean ("NSAllowsArbitraryLoads", true);
PlistElementArray LSApplicationQueriesSchemes =_rootDic.CreateArray("LSApplicationQueriesSchemes");
LSApplicationQueriesSchemes.AddString ("fbapi");
LSApplicationQueriesSchemes.AddString ("fb-messenger-api");
LSApplicationQueriesSchemes.AddString ("fbauth2");
LSApplicationQueriesSchemes.AddString ("fbshareextension");
File.WriteAllText(_plistPath, _plist.WriteToString());
}
}
}