JJBB/Assets/Plugins/Editor/iOS/PbxProjectSet.cs
2024-08-23 15:49:34 +08:00

192 lines
6.6 KiB
C#

#if UNITY_IOS || UNITY_IPHONE
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor.XCodeEditor;
using PBXProject = UnityEditor.iOS.Xcode.PBXProject;
public abstract class PbxProjectSet
{
// 需要特殊Flag的文件类型
protected static readonly Dictionary<string ,string> compileFlagDict = new Dictionary<string, string>
{
{ "OpenUDID.m", "-fno-objc-arc" }
};
protected static readonly string[] noBuildTypes =
{
".h",
".entitlements"
};
protected static readonly string[] noRelativePathTypes =
{
".framework",
".dylib",
".tbd",
".plist"
};
protected static readonly string[] noCopyTypes =
{
".txt",
".mdown",
".DS_Store"
};
protected readonly PBXProject pbxProject;
protected readonly string pbxProjectPath;
protected readonly string projectGuid;
private readonly string _releaseGuid;
private readonly string _runningGuid;
private readonly string _profilingGuid;
private readonly string _debugGuid;
protected readonly string sourcePath;
protected readonly string targetPath;
protected PbxProjectSet(string source, string target)
{
sourcePath = source.TrimEnd('/', '\\');
targetPath = target.TrimEnd('/', '\\');
pbxProjectPath = PBXProject.GetPBXProjectPath(target);
pbxProject = new PBXProject();
pbxProject.ReadFromFile(pbxProjectPath);
projectGuid = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName());
_debugGuid = pbxProject.BuildConfigByName(projectGuid, "Debug");
_releaseGuid = pbxProject.BuildConfigByName(projectGuid, "Release");
_profilingGuid = pbxProject.BuildConfigByName(projectGuid, "ReleaseForProfiling");
_runningGuid = pbxProject.BuildConfigByName(projectGuid, "ReleaseForRunning");
}
protected void ModifyCodes()
{
// 刘海适配代码
var src = @"_window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];";
var dst = @" CGRect winSize = [UIScreen mainScreen].bounds;
if((winSize.size.height == 1125 && winSize.size.width == 2436)
|| (winSize.size.height == 2436 && winSize.size.width == 1125)
|| (winSize.size.height == 1242 && winSize.size.width == 2688)
|| (winSize.size.height == 2688 && winSize.size.width == 1242)
|| (winSize.size.height == 828 && winSize.size.width == 1792))
{
winSize.size.width -= 150;
winSize.origin.x = 75;
}
_window = [[UIWindow alloc] initWithFrame: winSize];";
var unityAppControllerPath = targetPath + "/Classes/UnityAppController.mm";
var unityAppController = new XClassExt(unityAppControllerPath);
unityAppController.Replace(src, dst);
unityAppController.Dispose();
}
protected void AddDirectory(string directory, string projectDir)
{
AddDirectoryInternal(sourcePath.Open(directory), projectDir);
}
protected void AddFile(string filePath, string projectDir)
{
AddFileInternal(sourcePath.Open(filePath), projectDir);
}
protected void CopyFileOnly(string filePath, string projectDir)
{
CopyFileInternal(sourcePath.Open(filePath), projectDir);
}
private void AddDirectoryInternal(string directory, string projectDir)
{
if (Path.HasExtension(directory))
AddFileInternal(directory, projectDir);
else
{
var files = GetAllFiles(directory);
foreach (var file in files)
AddFileInternal(file, projectDir);
}
}
// 注:苹果的垃圾玩意会把文件夹当文件一样加入,所以不能直接扫描文件,只能一层一层扫描路径
private IEnumerable<string> GetAllFiles(string directory)
{
var result = new List<string>();
foreach (var file in Directory.GetFiles(directory))
{
var extension = Path.GetExtension(file);
if (!string.IsNullOrEmpty(extension) && !noCopyTypes.Contains(extension))
result.Add(file);
}
var subDirs = Directory.GetDirectories(directory);
foreach (var subDir in subDirs)
{
// 苹果的破文件夹形式的文件
if (!string.IsNullOrEmpty(Path.GetExtension(subDir)))
result.Add(subDir);
else
result.AddRange(GetAllFiles(subDir));
}
return result;
}
private void AddFileInternal(string filePath, string projectDir)
{
// 如果是.framework或者.bundle之类的垃圾玩意
if (Directory.Exists(filePath))
{
var files = Directory.GetFiles(filePath, "*.*", SearchOption.AllDirectories);
foreach (var file in files)
CopyFileInternal(file, projectDir);
}
else
{
CopyFileInternal(filePath, projectDir);
}
var extension = Path.GetExtension(filePath);
var path = filePath.Substring(sourcePath.Length + 1);
if (!string.IsNullOrEmpty(projectDir))
path = projectDir.Open(path);
var fileName = Path.GetFileName(path);
// Frameworks类单独使用特殊ProjectPath
var projectPath = noRelativePathTypes.Contains(extension) ? fileName : path;
var addFile = pbxProject.AddFile(path, projectPath);
// 不需要编译的类型不添加编译
if (!noBuildTypes.Contains(extension))
{
string compileFlags;
if (compileFlagDict.TryGetValue(fileName, out compileFlags))
pbxProject.AddFileToBuildWithFlags(projectGuid, addFile, compileFlags);
else
pbxProject.AddFileToBuild(projectGuid, addFile);
}
}
private void CopyFileInternal(string filePath, string projectDir)
{
var relative = filePath.Substring(sourcePath.Length + 1);
var target = targetPath.Open(projectDir).Open(relative);
var dir = Path.GetDirectoryName(target);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
File.Copy(filePath, target, true);
}
public abstract void Action();
protected abstract void SetTargetConfig(string guid);
protected void SetAllConfigs()
{
SetTargetConfig(_debugGuid);
SetTargetConfig(_releaseGuid);
SetTargetConfig(_runningGuid);
SetTargetConfig(_profilingGuid);
}
protected void Save()
{
File.WriteAllText(pbxProjectPath, pbxProject.WriteToString());
}
}
#endif