我们使用Unity为Xcode生成一个项目,并希望利用iMessage扩展,但唯一的方法就是在Unity生成Xcode项目之后进行扩展,所以每次我们构建项目时我们应该重新设置iMessage扩展。
虽然我们已将iMessage扩展名设为文件夹并保存在磁盘上,以便每次生成Xcode项目时我们都必须
这个程序很烦人,所以我们正在寻找其他方法,这很容易做到这一点。
有没有办法做到这一点?感谢。
答案 0 :(得分:1)
是的,你可以使用Unity xcode api 见https://bitbucket.org/Unity-Technologies/xcodeapi
基本上,您创建了一个构建后处理器,用于创建新目标并将贴纸资源添加到新生成的构建中。
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using MightyEditor.iOS.Xcode;
public class BuildPostProcessor
{
[PostProcessBuild(2000)]
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
{
Debug.Log("------ buildTarget:" + buildTarget + " path:" + buildPath);
if (buildTarget == BuildTarget.iOS)
{
string xcodeprojPath = buildPath + "/Unity-iPhone.xcodeproj";
string pbxprojPath = xcodeprojPath + "/project.pbxproj";
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile(pbxprojPath);
AddStickers(pbxProject, buildPath, xcodeprojPath, pbxprojPath);
pbxProject.WriteToFile(pbxprojPath);
}
}
private static void AddStickers(PBXProject pbxProject, string buildPath,string xcodeprojPath,string pbxprojPath)
{
string appGuid = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName());
DirectoryCopy("_Stickers", buildPath + "/Stickers", true);
string stickersGuid = pbxProject.AddAppExtension(appGuid, "stickers app", "com.apple.product-type.app-extension.messages-sticker-pack", "Stickers/Info.plist");
pbxProject.AddFile("Stickers/Stickers.xcassets", "Stickers/Stickers.xcassets");
pbxProject.AddFileToResourcesForTarget(stickersGuid, "Stickers/Stickers.xcassets");
pbxProject.AddBuildProperty(stickersGuid, "PRODUCT_BUNDLE_IDENTIFIER", "com.blABLA");
pbxProject.AddBuildProperty(stickersGuid, "TARGETED_DEVICE_FAMILY", "1,2");
pbxProject.AddBuildProperty(stickersGuid, "ASSETCATALOG_COMPILER_APPICON_NAME", "iMessage App Icon");
pbxProject.AddBuildProperty(stickersGuid, "ARCHS", "armv7 arm64");
pbxProject.SetBuildProperty(stickersGuid, "IPHONEOS_DEPLOYMENT_TARGET", "10.0");
pbxProject.SetBuildProperty(stickersGuid, "DEVELOPMENT_TEAM", "TEAMid");
//Info.plist update
string plistPath = buildPath + "/Stickers/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
// Get root
PlistElementDict rootDict = plist.root;
rootDict.values["CFBundleVersion"] = new PlistElementString(PlayerSettings.iOS.buildNumber);
rootDict.values["CFBundleShortVersionString"] = new PlistElementString(PlayerSettings.bundleVersion);
// Write to info.plist file
File.WriteAllText(plistPath, plist.WriteToString());
// This is quite yuck, but there isn't a way with Unity's PBX library to add a scheme and we need to add one for the Stickers target or else xcodebuild fails when we try to build it
File.WriteAllText(xcodeprojPath + "/xcshareddata/xcschemes/Stickers.xcscheme", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Scheme LastUpgradeVersion = \"0800\" wasCreatedForAppExtension = \"YES\" version = \"2.0\"><BuildAction parallelizeBuildables = \"YES\" buildImplicitDependencies = \"YES\"><BuildActionEntries><BuildActionEntry buildForTesting = \"YES\" buildForRunning = \"YES\" buildForProfiling = \"YES\" buildForArchiving = \"YES\" buildForAnalyzing = \"YES\"><BuildableReference BuildableIdentifier = \"primary\" BlueprintIdentifier = \"" + stickersGuid + "\" BuildableName = \"Stickers.appex\" BlueprintName = \"Stickers\" ReferencedContainer = \"container:Unity-iPhone.xcodeproj\"></BuildableReference></BuildActionEntry></BuildActionEntries></BuildAction><TestAction buildConfiguration = \"Debug\" selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\" selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\" shouldUseLaunchSchemeArgsEnv = \"YES\"><Testables></Testables><MacroExpansion><BuildableReference BuildableIdentifier = \"primary\" BlueprintIdentifier = \"" + appGuid + "\" BuildableName = \"Unity-Target-New.app\" BlueprintName = \"Unity-iPhone\" ReferencedContainer = \"container:Unity-iPhone.xcodeproj\"></BuildableReference></MacroExpansion><AdditionalOptions></AdditionalOptions></TestAction><LaunchAction buildConfiguration = \"Debug\" selectedDebuggerIdentifier = \"\" selectedLauncherIdentifier = \"Xcode.IDEFoundation.Launcher.PosixSpawn\" launchStyle = \"0\" useCustomWorkingDirectory = \"NO\" ignoresPersistentStateOnLaunch = \"NO\" debugDocumentVersioning = \"YES\" debugServiceExtension = \"internal\" allowLocationSimulation = \"YES\" launchAutomaticallySubstyle = \"2\"><AdditionalOptions></AdditionalOptions></LaunchAction><ProfileAction buildConfiguration = \"Release\" shouldUseLaunchSchemeArgsEnv = \"YES\" savedToolIdentifier = \"\" useCustomWorkingDirectory = \"NO\" debugDocumentVersioning = \"YES\" launchAutomaticallySubstyle = \"2\"><MacroExpansion><BuildableReference BuildableIdentifier = \"primary\" BlueprintIdentifier = \"" + stickersGuid + "\" BuildableName = \"Stickers.appex\" BlueprintName = \"Stickers\" ReferencedContainer = \"container:Unity-iPhone.xcodeproj\"></BuildableReference></MacroExpansion></ProfileAction><AnalyzeAction buildConfiguration = \"Debug\"></AnalyzeAction><ArchiveAction buildConfiguration = \"Release\" revealArchiveInOrganizer = \"YES\"></ArchiveAction></Scheme>");
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs, bool overrideDest = false)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists (destDirName)) {
Directory.CreateDirectory (destDirName);
}
else if(overrideDest)
{
Directory.Delete (destDirName, true);
Directory.CreateDirectory (destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, overrideDest);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs, overrideDest);
}
}
}
}
答案 1 :(得分:0)
我在团结 2018.4...
这是我为将贴纸嵌入过程自动化到 Unity 后期处理构建中所做的工作。
//
// Copyright (c) 2020 Cizcuz (ID)
// http://www.twitter.com/cizcuz
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEditor.iOS.Xcode.Extensions;
public class PostProcess
{
[PostProcessBuild(100)]
public static void OnPostProcessBuild(BuildTarget target, string buildPath)
{
if (target == BuildTarget.iOS)
{
// Add the sticker extension to current pbx
string PBXPath = PBXProject.GetPBXProjectPath(buildPath);
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile(PBXPath);
AddStickers(buildPath,pbxProject);
pbxProject.WriteToFile(PBXPath);
// After this, still need to fix app extension type
// I cant find any way to insert proper product Type from unity PBXProject class
string output = File.ReadAllText(PBXPath);
File.WriteAllText( PBXPath, output.Replace( "productType = \"com.apple.product-type.app-extension\"",
"productType = \"com.apple.product-type.app-extension.messages-sticker-pack\"" ) );
}
}
private static void AddStickers(string buildPath, PBXProject pbxProject)
{
const string StickerPackRelPath = ""; // INSERT relative path from <path to project folder>/Assets to your Sticker Asset i.e.: "/../../StickerAssets"
string stickerFolder = Path.GetFullPath( Application.dataPath + StickerPackRelPath );
if( Directory.Exists(stickerFolder) ) {
string PBXPath = PBXProject.GetPBXProjectPath(buildPath);
string appGuid = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName());
// Copy folder
FileUtil.CopyFileOrDirectory(stickerFolder, buildPath + "/Stickers");
//
string stickersGuid = pbxProject.AddAppExtension(appGuid, "My Stickers", "com.yourcompany.yourgame.stickers", "Stickers/Info.plist");
string stickerAssetGuid = pbxProject.AddFile("Stickers/Stickers.xcassets", "Stickers/Stickers.xcassets");
pbxProject.AddFile("Stickers/Info.plist","Stickers/Info.plist");
pbxProject.AddFileToBuild(stickersGuid, stickerAssetGuid);
string debugConfig = pbxProject.BuildConfigByName( stickersGuid, "Debug");
string releaseConfig = pbxProject.BuildConfigByName( stickersGuid, "Release");
string releaseProfilingConfig = pbxProject.BuildConfigByName( stickersGuid, "ReleaseForProfiling");
string releaseRunningConfig = pbxProject.BuildConfigByName( stickersGuid, "ReleaseForRunning");
List<string> allRelease = new List<string>() {
releaseConfig,
releaseProfilingConfig,
releaseRunningConfig
};
//
// This is just to match build properties normally exist when you
// create the Sticker AppExtension Target by XCode, not really sure if all of this is essential
//
pbxProject.AddBuildProperty( stickersGuid, "PRODUCT_BUNDLE_IDENTIFIER", "com.yourcompany.yourgame.stickers");
pbxProject.AddBuildProperty( stickersGuid, "TARGETED_DEVICE_FAMILY", "1,2"); // For me is iphone & ipad
pbxProject.AddBuildProperty( stickersGuid, "IPHONEOS_DEPLOYMENT_TARGET", "10.2"); // Sticker project supported in iOS 10
pbxProject.AddBuildProperty( stickersGuid, "COPY_PHASE_STRIP", "NO" );
pbxProject.AddBuildProperty( stickersGuid, "DEVELOPMENT_TEAM", ""); // INSERT #YOURTEAMID# HERE
pbxProject.AddBuildProperty( stickersGuid, "ALWAYS_SEARCH_USER_PATHS", "NO");
pbxProject.AddBuildProperty( stickersGuid, "CODE_SIGN_IDENTITY", "iPhone Developer" );
pbxProject.AddBuildProperty( stickersGuid, "CURRENT_PROJECT_VERSION", PlayerSettings.iOS.buildNumber );
pbxProject.AddBuildProperty( stickersGuid, "MARKETING_VERSION", PlayerSettings.bundleVersion );
pbxProject.AddBuildProperty( stickersGuid, "GCC_NO_COMMON_BLOCKS", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_C_LANGUAGE_STANDARD", "gnu11" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_WARN_64_TO_32_BIT_CONVERSION" ,"YES" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_NO_COMMON_BLOCKS", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_WARN_ABOUT_RETURN_TYPE", "YES_ERROR" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_WARN_UNDECLARED_SELECTOR", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_WARN_UNINITIALIZED_AUTOS", "YES_AGGRESSIVE" );
pbxProject.AddBuildProperty( stickersGuid, "GCC_WARN_UNUSED_FUNCTION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_CXX_LANGUAGE_STANDARD", "gnu++14" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_CXX_LIBRARY", "libc++" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_ENABLE_MODULES", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_ENABLE_OBJC_ARC", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_ENABLE_OBJC_WEAK", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "ENABLE_STRICT_OBJC_MSGSEND", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_BOOL_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_COMMA", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_CONSTANT_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_DIRECT_OBJC_ISA_USAGE", "YES_ERROR" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_EMPTY_BODY", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_ENUM_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_INFINITE_RECURSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_INT_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_NON_LITERAL_NULL_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_OBJC_LITERAL_CONVERSION", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_OBJC_ROOT_CLASS", "YES_ERROR" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_RANGE_LOOP_ANALYSIS", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_STRICT_PROTOTYPES", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_SUSPICIOUS_MOVE", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_UNGUARDED_AVAILABILITY", "YES_AGGRESSIVE" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN_UNREACHABLE_CODE", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_WARN__DUPLICATE_METHOD_MATCH", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_ANALYZER_NONNULL", "YES" );
pbxProject.AddBuildProperty( stickersGuid, "CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION", "YES_AGGRESSIVE" );
pbxProject.AddBuildProperty( stickersGuid, "MTL_FAST_MATH", "YES" );
pbxProject.AddBuildPropertyForConfig( debugConfig, "ONLY_ACTIVE_ARCH", "YES" );
pbxProject.AddBuildPropertyForConfig( debugConfig, "GCC_OPTIMIZATION_LEVEL", "0" );
pbxProject.AddBuildPropertyForConfig( debugConfig, "DEBUG_INFORMATION_FORMAT", "dwarf" );
pbxProject.AddBuildPropertyForConfig( debugConfig, "ENABLE_TESTABILITY", "YES" );
pbxProject.AddBuildPropertyForConfig( debugConfig, "MTL_ENABLE_DEBUG_INFO", "YES" );
pbxProject.AddBuildPropertyForConfig( allRelease, "ENABLE_NS_ASSERTIONS", "NO" );
pbxProject.AddBuildPropertyForConfig( allRelease, "MTL_ENABLE_DEBUG_INFO", "NO" );
pbxProject.AddBuildPropertyForConfig( allRelease, "VALIDATE_PRODUCT", "YES" );
// Sets property for asset catalog
pbxProject.AddBuildProperty(stickersGuid, "ASSETCATALOG_COMPILER_APPICON_NAME", "iMessage App Icon");
//Info.plist update
string plistPath = buildPath + "/Stickers/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
// Get root
PlistElementDict rootDict = plist.root;
rootDict.values["CFBundleVersion"] = new PlistElementString(PlayerSettings.iOS.buildNumber);
rootDict.values["CFBundleShortVersionString"] = new PlistElementString(PlayerSettings.bundleVersion);
// Update info.plist file
File.WriteAllText(plistPath, plist.WriteToString());
}
}
}