using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
#if UNITY_EDITOR_OSX && UNITY_IOS
using UnityEditor.iOS.Xcode;
public class Package {
[UnityEditor.Callbacks.PostProcessBuildAttribute(100)]
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject) {
if (target != BuildTarget.iOS) {
Debug.LogWarning("Target is not iPhone. XCodePostProcess will not run");
return;
}
// Create a new project object from build target
UnityEditor.iOS.Xcode.PBXProject project = new UnityEditor.iOS.Xcode.PBXProject();
string configFilePath = UnityEditor.iOS.Xcode.PBXProject.GetPBXProjectPath(pathToBuiltProject);
project.ReadFromFile(configFilePath);
string targetGuid = project.GetUnityMainTargetGuid();
string targetGuid_Framework = project.GetUnityFrameworkTargetGuid();
string debug = project.BuildConfigByName(targetGuid, "Debug");
string release = project.BuildConfigByName(targetGuid, "Release");
project.AddBuildPropertyForConfig(debug, "CODE_SIGN_RESOURCE_RULES_PATH", "$(SDKROOT)/ResourceRules.plist");
project.AddBuildPropertyForConfig(release, "CODE_SIGN_RESOURCE_RULES_PATH", "$(SDKROOT)/ResourceRules.plist");
#region
string projPath = Path.GetFullPath(pathToBuiltProject);
//添加推送和其他的有点不一样,需要添加一个文件。这个文件只能考进去。或者事先准备好了Base.entitlements 文件,文件类容 就是你手动添加进去的内容,你手动添加完成后生成的那个文件
string entitlement = Application.dataPath + "/Editor/entitlement.entitlements";
File.Copy (entitlement, pathToBuiltProject + "/Unity-iPhone/entitlement.entitlements");
//Max Ad Review service
File.Copy(Application.dataPath + "/ThirdParty/MaxSdk/AppLovin/Editor/AppLovinQualityServiceSetup-ios.rb", pathToBuiltProject + "/AppLovinQualityServiceSetup-ios.rb");
project.AddCapability(targetGuid, PBXCapabilityType.AssociatedDomains, pathToBuiltProject + "/Unity-iPhone/entitlement.entitlements", true);
// Enable Push Notifications
project.AddFrameworkToProject (targetGuid_Framework, "UserNotifications.framework", false);
// Enable background mode
// project.AddCapability (targetGuid, PBXCapabilityType.BackgroundModes);
#region google service plist file
// google service
string googleServicePath = Application.dataPath + "/Plugins/iOS/GoogleService-Info.plist";
File.Copy(googleServicePath, pathToBuiltProject + "/GoogleService-Info.plist");
project.AddFileToBuild(targetGuid, project.AddFile("GoogleService-Info.plist", "GoogleService-Info.plist", PBXSourceTree.Source));
#endregion
// Add background modes
string plistPath = pathToBuiltProject + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
PlistElementDict rootDict = plist.root;
//在playersetting里设置iosUseCustomAppBackgroundBehavior 和 iOSBackgroundModes
// PlistElementArray arr = rootDict.CreateArray ("UIBackgroundModes");
// arr.AddString ("remote-notification");
// arr.AddString ("fetch");
//解决错误:ITMS-90339
string exitsOnSuspendKey = "UIApplicationExitsOnSuspend";
if (rootDict.values.ContainsKey(exitsOnSuspendKey)) {
rootDict.values.Remove(exitsOnSuspendKey);
}
File.WriteAllText(plistPath, plist.WriteToString());
#endregion
// 根据实际需要添加framework或者tbd
// project.AddFrameworkToProject(targetGuid_Framework, "libz.tbd", false);
project.AddFrameworkToProject(targetGuid_Framework, "libsqlite3.tbd", false);
project.AddFrameworkToProject(targetGuid_Framework, "WebKit.framework", false);
// project.AddFrameworkToProject(targetGuid, "UnityFramework.framework", false);
// keychain
project.AddFrameworkToProject(targetGuid_Framework, "Security.framework", false);
// project.AddFrameworkToProject(targetGuid_Framework, "CoreTelephony.framework", false);
// AF
project.AddFrameworkToProject(targetGuid_Framework, "AdSupport.framework", false);
project.AddFrameworkToProject(targetGuid_Framework, "iAd.framework", false);
// AF END */
// adjust
project.AddFrameworkToProject(targetGuid_Framework, "AdServices.framework", false);
// ATT
project.AddFrameworkToProject(targetGuid_Framework, "AppTrackingTransparency.framework", false);
// ATT END
// 苹果登录
project.AddFrameworkToProject(targetGuid_Framework, "AuthenticationServices.framework", true);
// end
project.SetBuildProperty(targetGuid_Framework, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
project.SetBuildProperty(targetGuid, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
project.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
//处理iOS编译报错,大量Undefined symbol Swift.XXX
// project.SetBuildProperty(targetGuid_Framework, "SWIFT_OBJC_BRIDGING_HEADER", "Libraries/Plugins/iOS/Unity-iPhone-Bridging-Header.h");
// project.SetBuildProperty(targetGuid_Framework, "SWIFT_VERSION", "5.0");
// project.AddBuildProperty(targetGuid_Framework, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks");
//报错内容为:Please provide an auth token with USYM_UPLOAD_AUTH_TOKEN environment
// project.SetBuildProperty(targetGuid, "USYM_UPLOAD_AUTH_TOKEN", "FakeToken");
// project.SetBuildProperty(targetGuid_Framework, "USYM_UPLOAD_AUTH_TOKEN", "FakeToken");
//ITMS-90206,UnityFramework包含Framework问题
project.SetBuildProperty(targetGuid_Framework, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO");
project.WriteToFile(configFilePath);
// 编辑plist 文件
EditorPlist(Path.GetFullPath(pathToBuiltProject));
CopyDirectory(Application.dataPath + "../BFVersions/ios/ios_common", Path.GetFullPath(pathToBuiltProject), true);
}
static void CopyDirectory(string sourceDir, string destinationDir, bool recursive) {
// Get information about the source directory
var dir = new DirectoryInfo(sourceDir);
// Check if the source directory exists
if (!dir.Exists)
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
// Cache directories before we start copying
DirectoryInfo[] dirs = dir.GetDirectories();
// Create the destination directory
Directory.CreateDirectory(destinationDir);
// Get the files in the source directory and copy to the destination directory
foreach (FileInfo file in dir.GetFiles())
{
string targetFilePath = Path.Combine(destinationDir, file.Name);
file.CopyTo(targetFilePath);
}
// If recursive and copying subdirectories, recursively call this method
if (recursive)
{
foreach (DirectoryInfo subDir in dirs)
{
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
CopyDirectory(subDir.FullName, newDestinationDir, true);
}
}
}
private static void EditorPlist(string filePath) {
XCPlist list = new XCPlist(filePath);
string ITSAppUsesNonExemptEncryption = @"
ITSAppUsesNonExemptEncryption
";
//在plist里面增加ITSAppUsesNonExemptEncryption,解决上架AppStore提示缺少出口合规证明
list.AddKey(ITSAppUsesNonExemptEncryption);
// string AppsFlyerShouldSwizzle = @"
// AppsFlyerShouldSwizzle
// ";
// //appFlyer 设置 AppsFlyerShouldSwizzle,解决UnityAppController冲突,
// //记得AppsFlyerAppController.mm 注释掉//IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)
// list.AddKey(AppsFlyerShouldSwizzle);
// 跟踪权限请求描述(ATT) TODO...
string NSUserTrackingUsageDescription = @"
NSUserTrackingUsageDescription
Your data will help us to provide a more personalized experience and offers.";
list.AddKey(NSUserTrackingUsageDescription);
string NSLocationWhenInUseUsageDescription = @"
NSLocationWhenInUseUsageDescription
We need to use location information to provide you with better network services";
list.AddKey(NSLocationWhenInUseUsageDescription);
//iOS 设置状态栏的背景颜色方法
// string StatusBar = @"
// UIViewControllerBasedStatusBarAppearance
// ";
// list.AddKey(StatusBar);
//admob ironsource那里设置了
// string GADApplicationIdentifier = @"
// GADApplicationIdentifier
// ";
// list.AddKey(GADApplicationIdentifier);
//*/
//google Ads 使用 wkwebview
// string gad_preferred_webview = @"
// gad_preferred_webview
// wkwebview";
// list.AddKey(gad_preferred_webview);
// string UnityNotificationRequestAuthorizationOnAppLaunch = @"
// UnityNotificationRequestAuthorizationOnAppLaunch
// ";
// list.AddKey(UnityNotificationRequestAuthorizationOnAppLaunch);
string SKAdNetworkIdentifiers = @"
SKAdNetworkItems
SKAdNetworkIdentifier
2fnua5tdw4.skadnetwork
SKAdNetworkIdentifier
2u9pt9hc89.skadnetwork
SKAdNetworkIdentifier
3qcr597p9d.skadnetwork
SKAdNetworkIdentifier
3qy4746246.skadnetwork
SKAdNetworkIdentifier
3sh42y64q3.skadnetwork
SKAdNetworkIdentifier
424m5254lk.skadnetwork
SKAdNetworkIdentifier
4468km3ulz.skadnetwork
SKAdNetworkIdentifier
4dzt52r2t5.skadnetwork
SKAdNetworkIdentifier
4fzdc2evr5.skadnetwork
SKAdNetworkIdentifier
578prtvx9j.skadnetwork
SKAdNetworkIdentifier
5a6flpkh64.skadnetwork
SKAdNetworkIdentifier
7ug5zh24hu.skadnetwork
SKAdNetworkIdentifier
8c4e2ghe7u.skadnetwork
SKAdNetworkIdentifier
8s468mfl3y.skadnetwork
SKAdNetworkIdentifier
9rd848q2bz.skadnetwork
SKAdNetworkIdentifier
9t245vhmpl.skadnetwork
SKAdNetworkIdentifier
av6w8kgt66.skadnetwork
SKAdNetworkIdentifier
c6k4g5qg8m.skadnetwork
SKAdNetworkIdentifier
cstr6suwn9.skadnetwork
SKAdNetworkIdentifier
e5fvkxwrpn.skadnetwork
SKAdNetworkIdentifier
f38h382jlk.skadnetwork
SKAdNetworkIdentifier
hs6bdukanm.skadnetwork
SKAdNetworkIdentifier
kbd757ywx3.skadnetwork
SKAdNetworkIdentifier
klf5c3l5u5.skadnetwork
SKAdNetworkIdentifier
n6fk4nfna4.skadnetwork
SKAdNetworkIdentifier
p78axxw29g.skadnetwork
SKAdNetworkIdentifier
ppxm28t8ap.skadnetwork
SKAdNetworkIdentifier
prcb7njmu6.skadnetwork
SKAdNetworkIdentifier
s39g8k73mm.skadnetwork
SKAdNetworkIdentifier
t38b2kh725.skadnetwork
SKAdNetworkIdentifier
uw77j35x4d.skadnetwork
SKAdNetworkIdentifier
v4nxqhlyqp.skadnetwork
SKAdNetworkIdentifier
v72qych5uu.skadnetwork
SKAdNetworkIdentifier
wzmmz9fp6w.skadnetwork
SKAdNetworkIdentifier
yclnxrl5pm.skadnetwork
SKAdNetworkIdentifier
ydx93a7ass.skadnetwork
SKAdNetworkIdentifier
zq492l623r.skadnetwork
SKAdNetworkIdentifier
22mmun2rn5.skadnetwork
SKAdNetworkIdentifier
24t9a8vw3c.skadnetwork
SKAdNetworkIdentifier
275upjj5gd.skadnetwork
SKAdNetworkIdentifier
294l99pt4k.skadnetwork
SKAdNetworkIdentifier
32z4fx6l9h.skadnetwork
SKAdNetworkIdentifier
3l6bd9hu43.skadnetwork
SKAdNetworkIdentifier
3rd42ekr43.skadnetwork
SKAdNetworkIdentifier
4pfyvq9l8r.skadnetwork
SKAdNetworkIdentifier
523jb4fst2.skadnetwork
SKAdNetworkIdentifier
52fl2v3hgk.skadnetwork
SKAdNetworkIdentifier
54nzkqm89y.skadnetwork
SKAdNetworkIdentifier
5l3tpt7t6e.skadnetwork
SKAdNetworkIdentifier
5lm9lj6jb7.skadnetwork
SKAdNetworkIdentifier
5tjdwbrq8w.skadnetwork
SKAdNetworkIdentifier
6g9af3uyq4.skadnetwork
SKAdNetworkIdentifier
6xzpu9s2p8.skadnetwork
SKAdNetworkIdentifier
79pbpufp6p.skadnetwork
SKAdNetworkIdentifier
7rz58n8ntl.skadnetwork
SKAdNetworkIdentifier
9b89h5y424.skadnetwork
SKAdNetworkIdentifier
9nlqeag3gk.skadnetwork
SKAdNetworkIdentifier
9yg77x724h.skadnetwork
SKAdNetworkIdentifier
a8cz6cu7e5.skadnetwork
SKAdNetworkIdentifier
c3frkrj4fj.skadnetwork
SKAdNetworkIdentifier
cg4yq2srnc.skadnetwork
SKAdNetworkIdentifier
cj5566h2ga.skadnetwork
SKAdNetworkIdentifier
dkc879ngq3.skadnetwork
SKAdNetworkIdentifier
ejvt5qm6ak.skadnetwork
SKAdNetworkIdentifier
feyaarzu9v.skadnetwork
SKAdNetworkIdentifier
g28c52eehv.skadnetwork
SKAdNetworkIdentifier
ggvn48r87g.skadnetwork
SKAdNetworkIdentifier
glqzh8vgby.skadnetwork
SKAdNetworkIdentifier
gta9lk7p23.skadnetwork
SKAdNetworkIdentifier
k674qkevps.skadnetwork
SKAdNetworkIdentifier
kbmxgpxpgc.skadnetwork
SKAdNetworkIdentifier
ludvb6z3bs.skadnetwork
SKAdNetworkIdentifier
m5mvw97r93.skadnetwork
SKAdNetworkIdentifier
m8dbw4sv7c.skadnetwork
SKAdNetworkIdentifier
mlmmfzh3r3.skadnetwork
SKAdNetworkIdentifier
mtkv5xtk9e.skadnetwork
SKAdNetworkIdentifier
n66cz3y3bx.skadnetwork
SKAdNetworkIdentifier
n9x2a789qt.skadnetwork
SKAdNetworkIdentifier
nzq8sh4pbs.skadnetwork
SKAdNetworkIdentifier
pwa73g5rt2.skadnetwork
SKAdNetworkIdentifier
qqp299437r.skadnetwork
SKAdNetworkIdentifier
r45fhb6rf7.skadnetwork
SKAdNetworkIdentifier
rvh3l7un93.skadnetwork
SKAdNetworkIdentifier
tl55sbb4fm.skadnetwork
SKAdNetworkIdentifier
vcra2ehyfk.skadnetwork
SKAdNetworkIdentifier
wg4vff78zm.skadnetwork
SKAdNetworkIdentifier
x44k69ngh6.skadnetwork
SKAdNetworkIdentifier
x5l83yy675.skadnetwork
SKAdNetworkIdentifier
x8jxxk4ff5.skadnetwork
SKAdNetworkIdentifier
x8uqf25wch.skadnetwork
SKAdNetworkIdentifier
xy9t38ct57.skadnetwork
SKAdNetworkIdentifier
zmvfpc5aq8.skadnetwork
SKAdNetworkIdentifier
44jx6755aq.skadnetwork
SKAdNetworkIdentifier
44n7hlldy6.skadnetwork
SKAdNetworkIdentifier
4w7y6s5ca2.skadnetwork
SKAdNetworkIdentifier
6964rsfnh4.skadnetwork
SKAdNetworkIdentifier
6p4ks3rnbw.skadnetwork
SKAdNetworkIdentifier
737z793b9f.skadnetwork
SKAdNetworkIdentifier
74b6s63p6l.skadnetwork
SKAdNetworkIdentifier
84993kbrcf.skadnetwork
SKAdNetworkIdentifier
97r2b46745.skadnetwork
SKAdNetworkIdentifier
a2p9lx4jpn.skadnetwork
SKAdNetworkIdentifier
a7xqa6mtl2.skadnetwork
SKAdNetworkIdentifier
b9bk5wbcq9.skadnetwork
SKAdNetworkIdentifier
bxvub5ada5.skadnetwork
SKAdNetworkIdentifier
dzg6xy7pwj.skadnetwork
SKAdNetworkIdentifier
f73kdq92p3.skadnetwork
SKAdNetworkIdentifier
g2y4y55b64.skadnetwork
SKAdNetworkIdentifier
hdw39hrw9y.skadnetwork
SKAdNetworkIdentifier
krvm3zuq6h.skadnetwork
SKAdNetworkIdentifier
lr83yxwka7.skadnetwork
SKAdNetworkIdentifier
mls7yz5dvl.skadnetwork
SKAdNetworkIdentifier
mp6xlyr22a.skadnetwork
SKAdNetworkIdentifier
pwdxu55a5a.skadnetwork
SKAdNetworkIdentifier
rx5hdcabgc.skadnetwork
SKAdNetworkIdentifier
s69wq72ugq.skadnetwork
SKAdNetworkIdentifier
su67r6k2v3.skadnetwork
SKAdNetworkIdentifier
u679fj5vs4.skadnetwork
SKAdNetworkIdentifier
w9q455wk68.skadnetwork
SKAdNetworkIdentifier
y45688jllp.skadnetwork
SKAdNetworkIdentifier
n38lu8286q.skadnetwork
SKAdNetworkIdentifier
v9wttpbfk9.skadnetwork
SKAdNetworkIdentifier
252b5q8x7y.skadnetwork
SKAdNetworkIdentifier
9g2aggbj52.skadnetwork
SKAdNetworkIdentifier
238da6jt44.skadnetwork
SKAdNetworkIdentifier
x2jnk7ly8j.skadnetwork
SKAdNetworkIdentifier
488r3q3dtq.skadnetwork
SKAdNetworkIdentifier
f7s53z58qe.skadnetwork
SKAdNetworkIdentifier
v79kvwwj4g.skadnetwork
SKAdNetworkIdentifier
ecpz2srf59.skadnetwork
SKAdNetworkIdentifier
gvmwg8q7h5.skadnetwork
SKAdNetworkIdentifier
pu4na253f3.skadnetwork
SKAdNetworkIdentifier
yrqqpx2mcb.skadnetwork
SKAdNetworkIdentifier
z4gj7hsk7h.skadnetwork
";
list.AddKey(SKAdNetworkIdentifiers);
///*/facebook 深度连接
string facebookStr = @"
CFBundleURLTypes
CFBundleURLSchemes
fb277827051329111
FacebookAppID
277827051329111
FacebookClientToken
cd6be8cc57dff789f3476ee1b25e2410
FacebookDisplayName
Knights Combo
LSApplicationQueriesSchemes
fb
fbapi
fb-messenger-share-api
fbauth2
fbshareextension
fbapi20130214
fbapi20130410
fbapi20130702
fbapi20131010
fbapi20131219
fbapi20140410
fbapi20140116
fbapi20150313
fbapi20150629
fbapi20160328
fbauth
";
list.AddKey(facebookStr);
//*/
//保存
list.Save();
}
}
public partial class XClassExt : System.IDisposable {
private string filePath;
public XClassExt(string fPath) {
filePath = fPath;
if (!System.IO.File.Exists(filePath)) {
Debug.LogError(filePath + "not found in path.");
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 + " not found sign in " + 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 + " not found sign in " + below);
return;
}
text_all = text_all.Replace(below, newText);
StreamWriter streamWriter = new StreamWriter(filePath);
streamWriter.Write(text_all);
streamWriter.Close();
}
public void Dispose() {
}
}
public partial class XCPlist : System.IDisposable {
private string filePath;
List contents = new List();
List removeContents = new List();
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 RemoveKey(string contents) {
removeContents.Add(contents);
}
public void Save() {
StreamWriter saveFile = File.CreateText(filePath);
foreach (string line in contents)
saveFile.WriteLine(line);
saveFile.Close();
var texts = File.ReadAllText(filePath);
foreach (string content in removeContents) {
texts = texts.Replace(content, "");
};
File.WriteAllText(filePath, texts);
}
public void Dispose() {
}
}
#endif