LoginSignup
7
5

More than 3 years have passed since last update.

Unity Cloud BuildでFirebaseを使ったiOSアプリをビルドする

Posted at

Unity Cloud BuildではCocoapodが使えません。
なのでCocoapodを使わずにFirebaseの機能をiOSで使う方法を紹介します。

使えた機能

  • Analytics
  • Realtime Database
  • Authentication
  • Cloud Messaging
  • Dynamic Links 

UnityにFirebaseを実装する

FirebaseのSDKを入れる

まず ここ からFirebaseのUnity用のSDKをダウンロードします。
次にダウンロードしたSDKをUnityにインポートします。
[Assets]>[Import Package]>[Custom Package...]
2019-11-05 (3)_LI.jpg
ダウンロードしたzipファイルから使うものを選びます
Downloads\firebase_unity_sdk_6.6.0\firebase_unity_sdk\dotnet4\
↑このパスの中の Firebase???.unitypackage

iOSのFrameworkを入れる

次にFirebaseのiOS版のFrameworkを ここ からダウンロードします。
ダウンロードしたzipファイルを解凍し、使いたいFirebaseの機能のファイルを開く。

Analyticsの場合

[Downloads/Firebase-6.11.0/Firebase/Analytics]内のすべての .framework フォルダを
Unityの[Assets/Plugins/iOS]に入れます。
2019-11-05 (8).png
こんな感じでその他のframeworkも入れていきます。
frameworkが入れ終わったら、[Firebase-6.11.0\Firebase]内にある
[Firebase.h]というファイルも[Assets/Plugins/iOS]に入れます。

XcodeをC#で設定する

下のファイルを[Assets/Editor]内に置きます。

BuildProcess.cs

BuildProcess.cs
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
public class BuildProcess
{
    [PostProcessBuild]
    public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
    {
        // iOSじゃなければ処理しない
        if (buildTarget != BuildTarget.iOS)
        {
            return;
        }
        var project = new PBXProject();
        project.ReadFromFile(PBXProject.GetPBXProjectPath(path));
        var projectGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName());
        // Enable Modules (C and Objective-C)をYESに設定する
        project.SetBuildProperty(projectGuid, "CLANG_ENABLE_MODULES", "YES");
        project.SetBuildProperty(projectGuid, "ENABLE_BITCODE", "NO");
        project.WriteToFile(PBXProject.GetPBXProjectPath(path));
        string projPath = Path.Combine(path, "Unity-iPhone.xcodeproj/project.pbxproj");
        PBXProject proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(projPath));
        string target = proj.TargetGuidByName("Unity-iPhone");
        proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");// 必須!
        proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-l???");
/*
詳しくは下を参照
*/
        List<string> frameworks = new List<string>() {
            "???.framework"
        };
        foreach (var framework in frameworks)
        {
            proj.AddFrameworkToProject(target, framework, false);
        }
        File.WriteAllText(projPath, proj.WriteToString());
        CreateEntitlements(path, "myapp");
        SetCapabilities(path);// Push通知を使わないなら多分いらない
    }
    private static void CreateEntitlements(string path, string your_appname)
    {
        XmlDocument document = new XmlDocument();
        XmlDocumentType doctype = document.CreateDocumentType("plist", "-//Apple//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
        document.AppendChild(doctype);
        XmlElement plist = document.CreateElement("plist");
        plist.SetAttribute("version", "1.0");
        XmlElement dict = document.CreateElement("dict");
        plist.AppendChild(dict);
        document.AppendChild(plist);
        XmlElement e = (XmlElement)document.SelectSingleNode("/plist/dict");
        XmlElement key = document.CreateElement("key");
        key.InnerText = "aps-environment";
        e.AppendChild(key);
        XmlElement value = document.CreateElement("string");
        value.InnerText = "development";
        e.AppendChild(value);
        string entitlementsPath= Path.Combine(path, "Unity-iPhone/" + your_appname + ".entitlements");
         //= path + "/Unity-iPhone/" + your_appname + ".entitlements";
        document.Save(entitlementsPath);
        string projPath = Path.Combine(path, "Unity-iPhone.xcodeproj/project.pbxproj");
        PBXProject proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(projPath));
        string target = proj.TargetGuidByName("Unity-iPhone");
        string guid = proj.AddFile(entitlementsPath, entitlementsPath);
        proj.AddBuildProperty(target, "CODE_SIGN_ENTITLEMENTS", Path.Combine(path, "Unity-iPhone/" + your_appname + ".entitlements"));
        proj.AddFileToBuild(target, guid);
        proj.WriteToFile(projPath);
    }
    private static void SetCapabilities(string path)
    {
        string projPath = Path.Combine(path, "Unity-iPhone.xcodeproj/project.pbxproj");
        PBXProject proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(projPath));
        string target = proj.TargetGuidByName("Unity-iPhone");
        bool s=proj.AddCapability(target, PBXCapabilityType.PushNotifications);
        File.WriteAllText(projPath, proj.WriteToString());
        string[] lines = proj.WriteToString().Split('\n');
        List<string> newLines = new List<string>();
        bool editFinish = false;
        for (int i = 0; i < lines.Length; i++)
        {
            string line = lines[i];
            if (editFinish)
            {
                newLines.Add(line);
            }
            else if (line.IndexOf("isa = PBXProject;") > -1)
            {
                do
                {
                    newLines.Add(line);
                    line = lines[++i];
                } while (line.IndexOf("TargetAttributes = {") == -1);
                // この下のやつは多分無くても大丈夫 まあ、一応・・・
                newLines.Add("TargetAttributes = {");
                newLines.Add("********* = {");
                newLines.Add("DevelopmentTeam = ****;");
                newLines.Add("SystemCapabilities = {");
                newLines.Add("com.apple.BackgroundModes = {");
                newLines.Add("enabled = 1;");
                newLines.Add("};");
                newLines.Add("com.apple.Push = {");
                newLines.Add("enabled = 1;");
                newLines.Add("};");
                newLines.Add("};");
                newLines.Add("};");
                editFinish = true;
            }
            else
            {
                newLines.Add(line);
            }
        }
        File.WriteAllText(projPath, string.Join("\n", newLines.ToArray()));
    }
}

IOSBuildPostProcessor.cs

IOSBuildPostProcessor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;

public static class IOSBuildPostProcessor
{
    [PostProcessBuild]
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
    {
        if (target == BuildTarget.iOS)
        {
            OnPostprocessBuildIOS(pathToBuiltProject);//Dynamic Links用
            OnPostprocessBuildPush(pathToBuiltProject);//Cloud Messaging用
            OnPostprocessBuildbg(pathToBuiltProject);//Cloud Messaging用
        }
    }

    private static void OnPostprocessBuildIOS(string pathToBuiltProject)
    {
        //This is the default path to the default pbxproj file. Yours might be different
        string projectPath = "/Unity-iPhone.xcodeproj/project.pbxproj";
        //Default target name. Yours might be different
        string targetName = "Unity-iPhone";
        //Set the entitlements file name to what you want but make sure it has this extension
        string entitlementsFileName = "my_app.entitlements";

        var entitlements = new ProjectCapabilityManager(pathToBuiltProject + projectPath, entitlementsFileName, targetName);
        var domain = "???.page.link"; //ここにはDynamic Linksで設定した、???.page.linkなどを入れる
        entitlements.AddAssociatedDomains(new string[] { "applinks:" + domain });
        //Apply
        entitlements.WriteToFile();
    }
    private static void OnPostprocessBuildPush(string pathToBuiltProject)
    {
        //This is the default path to the default pbxproj file. Yours might be different
        string projectPath = "/Unity-iPhone.xcodeproj/project.pbxproj";
        //Default target name. Yours might be different
        string targetName = "Unity-iPhone";
        //Set the entitlements file name to what you want but make sure it has this extension
        string entitlementsFileName = "my_app_2.entitlements";

        var entitlements = new ProjectCapabilityManager(pathToBuiltProject + projectPath, entitlementsFileName, targetName);
        entitlements.AddPushNotifications(true);
        //Apply
        entitlements.WriteToFile();
    }
    private static void OnPostprocessBuildbg(string pathToBuiltProject)
    {
        //This is the default path to the default pbxproj file. Yours might be different
        string projectPath = "/Unity-iPhone.xcodeproj/project.pbxproj";
        //Default target name. Yours might be different
        string targetName = "Unity-iPhone";
        //Set the entitlements file name to what you want but make sure it has this extension
        string entitlementsFileName = "my_app_3.entitlements";

        var entitlements = new ProjectCapabilityManager(pathToBuiltProject + projectPath, entitlementsFileName, targetName);
        entitlements.AddBackgroundModes(BackgroundModesOptions.RemoteNotifications);
        //Apply
        entitlements.WriteToFile();
    }
}

長いですね・・・
コメントを見て少し書き換えたりしてください。

BuildProcess.csを書き換える

BuildProcess.cs

        proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");// 必須!
        proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-l???");
        List<string> frameworks = new List<string>() {
            "???.framework"
        };

上のBuildProcess.csにこんな行があると思います
ここをframeworkファイル内のmodule.modulemapに沿って書き換えます。

例 Analyticsの場合

場所 [FirebaseAnalytics.framework/Modules/module.modulemap]

module.modulemap
framework module FirebaseAnalytics {
  umbrella header "FirebaseAnalytics.h"
  export *
  module * { export * }
  link "sqlite3"
  link "z"
  link framework "CoreData"
  link framework "Security"
  link framework "StoreKit"
  link framework "SystemConfiguration"
  link framework "UIKit"
}

と書いてある場合は
proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");// 必須!
の下に
proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-lz");
proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-lsqlite3");
を追加します。
要するに
"-l"+"link の後に書いているもの"
を追加します。
link frameworkの部分は、
List<string> frameworks = new List<string>() {
の中に上の例では

"CoreData.framework",
"Security.framework",
"StoreKit.framework",
"SystemConfiguration.framework",
"UIKit.framework"

を追加します。

こんな感じで他のframeworkのmodule.modulemapを見て追加します。

後はビルドしてみましょう!
そうすれば多分できるはずです。

わからないことやエラーが起きたらコメントで知らせてください。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5