首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Xcode制作一个imessage扩展包以便可以导入

如何使用Xcode制作一个imessage扩展包以便可以导入
EN

Stack Overflow用户
提问于 2017-10-02 12:00:59
回答 2查看 829关注 0票数 0

我们使用团结为Xcode生成一个项目,并希望利用iMessage扩展的优势,但唯一的方法是在团结生成Xcode项目之后进行扩展,所以每次构建我们的项目时,我们都应该重新设置iMessage扩展。

虽然我们已经使iMessage扩展成为一个文件夹并保存在磁盘上,所以每次生成Xcode项目时,我们都必须

  1. 使用Xcode添加iMessage扩展特性。
  2. 将一些东西拖到Xcode中,用预置代码覆盖生成的代码。

这个过程很烦人,所以我们正在寻找其他的方法,这是很容易做到的。

有办法这样做吗?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2017-10-26 12:49:10

是的,您可以为此使用Unity api (请参阅https://bitbucket.org/Unity-Technologies/xcodeapi )

基本上,您创建一个构建后处理器,它创建一个新的目标,并将粘贴资源添加到新生成的构建中。

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2020-12-20 04:33:51

我要团结2018.4.

下面是我为自动化贴纸所做的工作--将过程嵌入到统一后流程构建中。

  • 将粘贴资产复制到文件夹中,相对于统一项目资产路径
  • 对我来说,这个文件夹包含Stickers.xcassets和Info.plist。(以前由XCode生成)
  • 将此后处理类添加到项目中。
代码语言:javascript
运行
复制
//
// 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());
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46525060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档