Unity で iOS のアプリをビルドするとき、毎回手動で実行するのは面倒くさい。 fastlane を使って、Unity プロジェクトから XCode プロジェクトを書き出して ipa を作成するまでを自動化する。

今回は、Xcode プロジェクトを書き出して、設定を編集するところまで。

※ fastlane は後編まで出てきません。

追記:後編 書いた :memo:

概要

  • BuildPipeline API (C#) を使って、Xcode プロジェクトを書き出す
  • UnityEditor.iOS.Xcode (C#) を使って、Xcode の設定を編集する
  • fastlane (Ruby) を使って、ipa をビルドする 後編に続く

環境

  • Unity 5.3.2f1
  • fastlane 1.81.0

Xcode プロジェクトを書き出す

Unity - Scripting API: BuildPipeline.BuildPlayer を使って、プロジェクトを書き出すことができる。

Editor/Builder.cs

using UnityEngine;
using UnityEditor;
using System.Linq;

public class Builder
{
    private static readonly string BuildPath = "Build";

    private static string ProductName { get { return PlayerSettings.productName; } }

    private static string IPABuildPath { get { return string.Format("{0}.ipa", ProductName); } }

    private static string[] GetScenes()
    {
        return EditorBuildSettings.scenes
            .Where(scene => !scene.path.EndsWith("Test.unity"))
            .Select(scene => scene.path)
            .ToArray();
    }

    [UnityEditor.MenuItem("Tools/Builder/Clean %#k")]
    static void CleanBuild()
    {
        FileUtil.DeleteFileOrDirectory(BuildPath);
        FileUtil.DeleteFileOrDirectory(IPABuildPath);
    }

    [UnityEditor.MenuItem("Tools/Builder/Build iOS %#i")]
    public static void BuildiOS()
    {
        const BuildTarget target = BuildTarget.iOS;

        EditorUserBuildSettings.SwitchActiveBuildTarget(target);
        PlayerSettings.iOS.sdkVersion = iOSSdkVersion.DeviceSDK;
        BuildOptions options = BuildOptions.SymlinkLibraries;

        string error = BuildPipeline.BuildPlayer(GetScenes(), BuildPath, target, options);
        if (!string.IsNullOrEmpty(error))
        {
            throw new UnityException(error);
        }
    }
}

[UnityEditor.MenuItem] を付けると、UnityEditor のメニューに表示できたり、キーボードショートカットを設定できたりして便利。

Xcode の設定を編集する

Unity - Scripting API: PostProcessBuildAttribute を使うと、プロジェクトのビルドを Hook して、任意のメソッドを実行することができる。メソッドの中で、 Unity - Scripting API: PBXProjectUnity - Scripting API: PlistDocument を使って、 Xcode プロジェクトの設定を編集する。

Editor/XcodeProjectConfigurator

using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.Diagnostics;
using System.IO;

public class XcodeProjectConfigurator
{
    [PostProcessBuild]
    static void OnPostprocessBuild(BuildTarget buildTarget, string buildPath)
    {
        if (buildTarget != BuildTarget.iOS)
            return;

        ConfigurePlist(buildPath, "Info.plist");
        ConfigurePorject(buildPath, "Unity-iPhone.xcodeproj");
    }

    static void ConfigurePlist(string buildPath, string plistPath)
    {
        var plist = new PlistDocument();
        var path = Path.Combine(buildPath, plistPath);

        plist.ReadFromFile(path);

        plist.root.SetString("CFBundleDevelopmentRegion", "ja_JP");

        plist.WriteToFile(path);
    }
    
    static void ConfigurePorject(string buildPath, string projectPath)
    {
        var project = new PBXProject();
        var path = Path.Combine(Path.Combine(buildPath, projectPath), "project.pbxproj");

        project.ReadFromFile(path);

        var target = project.TargetGuidByName("Unity-iPhone");

        project.SetBuildProperty(target, "ENABLE_BITCODE", "NO");

        project.WriteToFile(path);
    }
}

ポイントは以下のとおり。

  • [PostProcessBuild] では、特定の BuildTarget だけ Hook することはできないので、 メソッドの引数に渡される BuildTarget でフィルタする。
  • 日本語化のために、デフォルト言語を日本語にする。
  • Bitcode コンパイルオプションが有効だと ipa ビルドに失敗するので、無効にしておく。

Builder.cs をエディタから実行する

メニュー > Tools > Builder > Build iOS で実行できる。また、Builder.cs で定義したショートカット(Shift + Cmd + i)でも実行できる。

Builder.cs を CLI から実行する

Unity エディタの実行ファイルを CLI から実行すれば良い。

/Applications/Unity/Unity.app/Contents/MacOS/Unity \
  -projectPath "/path/to/your/Product" \
  -quit \
  -batchmode \
  -executeMethod "Builder.BuildiOS"

-quit オプションを付けておくと、ビルド中にエラーになったときにも Unity エディタが terminate しないので、CI でビルドするときに便利。 CLI から実行時に既に Unity エディタが立ち上がっているとエラーになるので、注意する。 ので、開発中にローカルマシンでビルドしたいときは、だいたいエディタから実行することになる。

その他オプションなど詳しくは Unity - Manual: Command line arguments を参照する。

ipa をビルドする

後編に続く。

まとめ・感想

  • BuildPipeline API (C#) を使って、スクリプトで Xcode プロジェクトを書き出せるようにした
    • [UnityEditor.MenuItem] で、Unity エディタのメニューから実行できるようにした
  • UnityEditor.iOS.Xcode (C#) を使って、Xcode の設定を編集した
    • [PostProcessBuild] でビルドを Hook して、ビルド後に自動で設定できるようにした
  • ビルドスクリプト Builder.BuildiOS を CLI から実行してみた

PBXProject や PlistDocument のドキュメントが有って無いようなものなので、使い方を把握するのに苦労した。

xcodebuild コマンドを使えば、Xcode プロジェクトからアーカイブを作成したり、ipa を作成したりできる。 ので、シェルスクリプト化して使っていたけど、最近 fastlane に乗り換えたらスクリプトの可読性があがって良かったので、 後編では fastlane を使って ipa を作成する予定。

追記:後編 書いた :memo:

参考