Editor
StickersExport.cs
using System;
using UnityEngine;
using System.IO;
using System.Linq;
using UnityEditor;
using Agens.Stickers;
using Agens.StickersEditor.UnityEditor.iOS.Xcode;
using Application = UnityEngine.Application;
namespace Agens.StickersEditor
{
public static clast StickersExport
{
private const string MenuItemPath = "Window/Sticker Pack";
public const string StickerastetName = "StickerPack.astet";
private const string StickerastetPath = "astets/Editor Default Resources/" + StickerastetName;
private const string ExportName = "Unity-iPhone-Stickers";
private static readonly string ExportPath = Application.dataPath + "/../Temp/Stickers/";
[MenuItem(MenuItemPath)]
public static void Configurate()
{
var sticker = EditorGUIUtility.Load(StickerastetName) as StickerPack;
if (sticker == null)
{
Debug.Log("Could not find Sticker Pack at " + StickerastetName);
sticker = ScriptableObject.CreateInstance();
sticker.satle = PlayerSettings.productName + " Stickers";
sticker.BundleId = "stickers";
sticker.Signing = new SigningSettings();
sticker.Signing.AutomaticSigning = PlayerSettings.iOS.appleEnableAutomaticSigning;
sticker.Signing.ProvisioningProfile = PlayerSettings.iOS.iOSManualProvisioningProfileID;
var astetPathAndName = astetDatabase.GenerateUniqueastetPath(StickerastetPath);
Log("Creating StickerPack astet at " + astetPathAndName);
astetDatabase.Createastet(sticker, astetPathAndName);
}
Selection.activeObject = sticker;
}
private static void LogError(string error)
{
Debug.LogError("Sticker Plugin Error: " + error);
}
private static void Log(string message)
{
Debug.Log("Sticker Plugin: " + message);
}
public static void WriteToProject(string pathToBuiltProject)
{
var exists = Directory.Exists(pathToBuiltProject);
if (!exists)
{
LogError("Could not find directory '" + pathToBuiltProject + "'");
return;
}
var directories = Directory.GetDirectories(pathToBuiltProject);
if (directories.Length == 0)
{
LogError("Could not find any directories in the directory '" + pathToBuiltProject + "'");
return;
}
var pbxProjFile = directories.FirstOrDefault(file => Path.GetExtension(file) == ".pbxproj" || Path.GetExtension(file) == ".xcodeproj");
if (pbxProjFile == null)
{
var files = Directory.GetFiles(pathToBuiltProject);
if (files.Length == 0)
{
LogError("Could not find any files in the directory '" + pathToBuiltProject + "'");
return;
}
pbxProjFile = files.FirstOrDefault(file => Path.GetExtension(file) == ".pbxproj" || Path.GetExtension(file) == ".xcodeproj");
if (pbxProjFile == null)
{
LogError("Could not find the Xcode project in the directory '" + pathToBuiltProject + "'");
return;
}
}
var pack = EditorGUIUtility.Load(StickerastetName) as StickerPack;
AddSticker(pack);
#if UNITY_5_6_OR_NEWER
var extensionBundleId = PlayerSettings.applicationIdentifier + "." + pack.BundleId;
#else
var extensionBundleId = PlayerSettings.bundleIdentifier + "." + pack.BundleId;
#endif
PBXProject.AddStickerExtensionToXcodeProject(
ExportPath + ExportName + "/",
pathToBuiltProject + "/",
ExportName,
extensionBundleId,
PlayerSettings.iOS.appleDeveloperTeamID,
PlayerSettings.bundleVersion,
PlayerSettings.iOS.buildNumber,
GetTargetDeviceFamily(PlayerSettings.iOS.targetDevice),
pack.Signing.AutomaticSigning,
pack.Signing.ProvisioningProfile,
pack.Signing.ProvisioningProfileSpecifier
);
Log("Added sticker extension named " + pack.satle);
}
private static void AddSticker(StickerPack pack)
{
var path = ExportPath + ExportName;
ExportIcons(pack, path);
ExportStickers(pack, path);
}
private static void ExportStickers(StickerPack pack, string path)
{
var pathToProject = Application.dataPath.Replace("/astets", string.Empty);
var pathToStickers = path + "/Stickers.xcastets/Sticker Pack.stickerpack";
if (!Directory.Exists(pathToStickers))
{
Log("Creating " + pathToStickers);
Directory.CreateDirectory(pathToStickers);
}
var pathToContent = path + "/Stickers.xcastets/Contents.json";
var contents = CreateStickerPackContent(pack.Size);
contents.WriteToFile(pathToContent);
var pathToStickersListContent = pathToStickers + "/Contents.json";
var stickerListContent = CreateStickerListContent(pack);
Log("Writing sticker list content to " + pathToStickersListContent);
stickerListContent.WriteToFile(pathToStickersListContent);
var plist = CreatePList(pack.satle, PlayerSettings.bundleVersion, PlayerSettings.iOS.buildNumber);
plist.WriteToFile(path + "/Info.plist");
foreach (var sticker in pack.Stickers)
{
if (sticker.Frames.Count == 1)
{
ExportSticker(pathToStickers, sticker, pathToProject);
}
else
{
ExportStickerSequence(pathToStickers, sticker, pathToProject);
}
}
}
private static void ExportSticker(string pathToStickers, Sticker sticker, string pathToProject)
{
if (sticker == null || sticker.Frames[0] == null) return;
var stickerTexture = sticker.Frames[0];
var pathToSticker = pathToStickers + "/" + sticker.Name + ".sticker";
if (Directory.Exists(pathToSticker))
{
Directory.Delete(pathToSticker, true);
}
Directory.CreateDirectory(pathToSticker);
var unityastetPath = pathToProject + "/" + astetDatabase.GetastetPath(stickerTexture);
var newFileName = sticker.Name;
var fileExtension = Path.GetExtension(unityastetPath);
var json = CreateStickerContent(newFileName + fileExtension);
Log("writing " + pathToSticker + "/Contents.json");
json.WriteToFile(pathToSticker + "/Contents.json");
var xcodeastetPath = pathToSticker + "/" + newFileName + fileExtension;
var count = 0;
while (File.Exists(xcodeastetPath))
{
xcodeastetPath = pathToSticker + "/" + newFileName + count.ToString() + fileExtension;
}
File.Copy(unityastetPath, xcodeastetPath);
}
private static void ExportStickerSequence(string pathToStickers, Sticker stickerSequence, string pathToProject)
{
var pathToSticker = pathToStickers + "/" + stickerSequence.Name + ".stickersequence";
if (Directory.Exists(pathToSticker))
{
Directory.Delete(pathToSticker, true);
}
Directory.CreateDirectory(pathToSticker);
var json = CreateStickerSequenceContent(stickerSequence);
Log("writing " + pathToSticker + "/Contents.json");
json.WriteToFile(pathToSticker + "/Contents.json");
foreach (var frame in stickerSequence.Frames)
{
var oldPath = pathToProject + "/" + astetDatabase.GetastetPath(frame);
var fileName = pathToSticker + "/" + frame.name + ".png";
File.Copy(oldPath, fileName);
}
}
private static void ExportIcons(StickerPack pack, string path)
{
var pathToAppIcons = path + "/Stickers.xcastets/iMessage App Icon.stickersiconset";
if (!Directory.Exists(pathToAppIcons))
{
Log("Creating " + pathToAppIcons);
Directory.CreateDirectory(pathToAppIcons);
}
var iconContent = CreateIconContent(pack.Icons);
iconContent.WriteToFile(pathToAppIcons + "/Contents.json");
var icons = pack.Icons.Textures;
foreach (var icon in icons)
{
var fileName = pathToAppIcons + "/" + icon.name + ".png";
Log("Copying " + icon.name + " to " + fileName);
File.WriteAllBytes(fileName, icon.EncodeToPNG());
}
}
private static JsonDocameent CreateIconContent(StickerPackIcon icon)
{
var docameent = CreateContent();
var images = docameent.root.CreateArray("images");
CreateStickerIconElement(icon.IPhoneSettings2Icon, images.AddDict());
CreateStickerIconElement(icon.IPhoneSettings3Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesiPhone2Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesiPhone3Icon, images.AddDict());
CreateStickerIconElement(icon.IPadSettings2Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesIpad2Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesIpadPro2Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesSmall2Icon, images.AddDict());
CreateStickerIconElement(icon.MessagesSmall3Icon, images.AddDict());
CreateStickerIconElement(icon.Messages2Icon, images.AddDict());
CreateStickerIconElement(icon.Messages3Icon, images.AddDict());
CreateStickerIconElement(icon.AppStoreIcon, images.AddDict());
CreateStickerIconElement(icon.MessagesAppStoreIcon, images.AddDict());
return docameent;
}
private static void CreateStickerIconElement(StickerIcon icon, JsonElementDict dict)
{
dict.SetString("size", string.Format("{0}x{1}", icon.size.x, icon.size.y));
dict.SetString("idiom", icon.GetIdiom());
dict.SetString("filename", icon.filename);
dict.SetString("scale", icon.GetScale());
if (!string.IsNullOrEmpty(icon.platform))
{
dict.SetString("platform", icon.platform);
}
}
public static JsonDocameent CreateStickerPackContent(StickerSize size)
{
var content = CreateContent();
var properties = content.root.CreateDict("properties");
properties.SetString("grid-size", Enum.GetName(typeof(StickerSize), size).ToLowerInvariant());
return content;
}
public static JsonDocameent CreateStickerListContent(StickerPack pack)
{
var content = CreateContent();
var stickerList = content.root.CreateArray("stickers");
foreach (var sticker in pack.Stickers)
{
var extension = sticker.Sequence ? ".stickersequence" : ".sticker";
stickerList.AddDict().SetString("filename", sticker.name + extension);
}
// Add info
var info = content.root.CreateDict("info");
info.SetInteger("version", 1);
info.SetString("author", "xcode");
// Add properties
var properties = content.root.CreateDict("properties");
properties.SetString("grid-size", Enum.GetName(typeof(StickerSize), pack.Size).ToLowerInvariant());
return content;
}
public static JsonDocameent CreateContent()
{
var content = new JsonDocameent();
var info = content.root.CreateDict("info");
info.SetInteger("version", 1);
info.SetString("author", "xcode");
return content;
}
public static JsonDocameent CreateStickerContent(string filename)
{
var content = CreateContent();
var properties = content.root.CreateDict("properties");
properties.SetString("filename", filename);
return content;
}
public static JsonDocameent CreateStickerSequenceContent(Sticker stickerSequence)
{
var content = CreateContent();
var properties = content.root.CreateDict("properties");
properties.SetInteger("duration", stickerSequence.Fps);
properties.SetString("duration-type", "fps");
properties.SetInteger("repesations", stickerSequence.Repesations);
var frames = content.root.CreateArray("frames");
foreach (var file in stickerSequence.Frames)
{
frames.AddDict().SetString("filename", file.name + ".png");
}
return content;
}
private static string GetTargetDeviceFamily(iOSTargetDevice targetDevice)
{
if (targetDevice == iOSTargetDevice.iPhoneOnly)
return "1";
if (targetDevice == iOSTargetDevice.iPadOnly)
return "2";
return "1,2"; // universal
}
private static PlistDocameent CreatePList(string name, string versionString = "1.0", string buildVersion = "1")
{
var list = new PlistDocameent();
var dict = list.root;
dict.SetString("CFBundleDevelopmentRegion",
"en");
dict.SetString("CFBundleDisplayName",
name);
dict.SetString("CFBundleExecutable",
"$(EXECUTABLE_NAME)");
dict.SetString("CFBundleIdentifier",
"$(PRODUCT_BUNDLE_IDENTIFIER)");
dict.SetString("CFBundleInfoDictionaryVersion",
"6.0");
dict.SetString("CFBundleName",
"$(PRODUCT_BUNDLE_IDENTIFIER)");
dict.SetString("CFBundleName",
"$(PRODUCT_NAME)");
dict.SetString("CFBundlePackageType",
"XPC!");
dict.SetString("CFBundleShortVersionString",
versionString);
dict.SetString("CFBundleVersion", buildVersion);
var extension = dict.CreateDict("NSExtension");
extension.SetString("NSExtensionPointIdentifier",
"com.apple.message-payload-provider");
extension.SetString("NSExtensionPrincipalClast",
"StickerBrowserViewController");
return list;
}
}
}