Help us understand the problem. What is going on with this article?

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

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を見て追加します。

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした