每次打包都要手动修改Xcode的各种配置,于是研究了一下通过Unity提供的API设置XCode的各种配置
//xxxx为你的证书的ID
PlayerSettings.iOS.appleDeveloperTeamID = xxxx;
PlayerSettings.iOS.appleEnableAutomaticSigning = true;
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget bulidTarget, string path)
{
//Debug.Log("iOS 打包回调配置");
if (bulidTarget != BuildTarget.iOS) return;
//基础配置,得到工程的targetGuid
string projectPath = PBXProject.GetPBXProjectPath(path);
PBXProject project = new PBXProject();
string fileText = File.ReadAllText(projectPath);
project.ReadFromString((fileText));
string targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName());
//"z.entitlemests"名字自取
var capManager = new ProjectCapabilityManager(projectPath, "z.entitlements", PBXProject.GetUnityTargetName());
//capability设置
SetCapabilities(capManager);
//BuildSetting
SetBuidSetting(project, targetGuid, projectPath);
//framework
AddFramework(project, targetGuid, projectPath);
//plist文件
AddPlist(path);
//代码
AddiosCode(path);
}
private static void SetCapabilities(ProjectCapabilityManager manager)
{
//推送
manager.AddPushNotifications(true);
//内购
manager.AddInAppPurchase();
manager.WriteToFile();
}
设置XCode自带的Framework,至于第三方库,放到Unity工程的Plungins/iOS目录下会自动引用
string[] umengFrameworkArr = { "libz.dylib", "CoreTelephony.framework", "libz.tbd", "libsqlite3.tbd", "CoreGraphics.framework" };
foreach (string str in umengFrameworkArr)
{
project.AddFrameworkToProject(targetGuid,str,false);
}
设置XCode BuildSetting
string linkerFlag = "OTHER_LDFLAGS";
project.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
project.AddBuildProperty(targetGuid, linkerFlag, "-ObjC");
project.AddBuildProperty(targetGuid, linkerFlag, "-all_load");
project.AddBuildProperty(targetGuid, linkerFlag, "-licucore");
效果如图:每个属性的名字在右边的Quick Help中可以看到
static void AddPlist(string projPath)
{
string plistPath = projPath + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
PlistElementDict rootDic = plist.root;
//不设置这项,提交时会显示缺少合规证明
rootDic.SetBoolean("ITSAppUsesNonExemptEncryption", false);
rootDic.SetString("NSCameraUsageDescription", "$(PRODUCT_NAME)想用下你的相机啦"); //相机
rootDic.SetString("NSMicrophoneUsageDescription", "$(PRODUCT_NAME)想要使用麦克风");//mic
rootDic.SetString("NSPhotoLibraryUsageDescription", "$(PRODUCT_NAME)想要访问相册");
rootDic.SetString("NSLocationWhenInUseUsageDescription", "$(PRODUCT_NAME)需要获取您的当前位置");
PlistElementArray urlTypes = rootDic.CreateArray("CFBundleURLTypes");
string[] urlSchemes = { "微信key","腾讯qqKey","QQ16进制"};
foreach(string str in urlSchemes)
{
PlistElementDict typeRole = urlTypes.AddDict();
typeRole.SetString("CFBundleTypeRole", "Editor");
PlistElementArray urlScheme = typeRole.CreateArray("CFBundleURLSchemes");
urlScheme.AddString(str);
}
PlistElementArray queriesSchemes = rootDic.CreateArray("LSApplicationQueriesSchemes");
string[] queriesArr = { "mqqapi",
"mqq",
"mqqOpensdkSSoLogin",
"mqqconnect",
"mqqopensdkdataline",
"mqqopensdkgrouptribeshare",
"mqqopensdkfriend",
"mqqopensdkapi",
"mqqopensdkapiV2",
"mqqopensdkapiV3",
"mqqopensdkapiV4",
"mqzoneopensdk",
"wtloginmqq",
"wtloginmqq2",
"mqqwpa",
"mqzone",
"mqzonev2",
"mqzoneshare",
"wtloginqzone",
"mqzonewx",
"mqzoneopensdkapiV2",
"mqzoneopensdkapi19",
"mqzoneopensdkapi",
"mqqbrowser",
"mttbrowser",
"wechat",
"weixin"};
foreach(string str in queriesArr)
{
queriesSchemes.AddString(str);
}
PlistElementDict arbitraryLoad = rootDic.CreateDict("NSAppTransportSecurity");
arbitraryLoad.SetBoolean("NSAllowsArbitraryLoads", true);
File.WriteAllText(plistPath, plist.WriteToString());
//根据路径获取OC文件
XClass UnityAppController = new XClass(projectPath+"/Classes/UnityAppController.mm");
//查找是否有#include "AppDelegateListener.h"这行代码,有的话则在这行代码下面添加#import
UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"",
"#import ");
UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"",
"#import \"UNUMConfigure.h\" ");
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
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();
if (text_all.Contains(text)) text_all.Replace(text, string.Empty);
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()
{
}
}