UnityでXcodeのプロジェクト設定を自動化したい(c#でPostProcessBuildを書く場合)

  • 38
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Unity で iOS アプリを作っていると、一度はXcodeのプロジェクト設定を自動化したいと思うはず。例えば、Framework を追加したり、Other Linker Flags に "-ObjC" を追加したり。
ググると Ruby を使う例はたくさん出てきますが、C# を使う例はあまり見つからなかったのでまとめてみました。

仕組み

Unity でプロジェクト設定を自動で行うには

  • PostprocessBuildPlayer という sh コマンドまたは Perl スクリプトを使う方法
  • PostProcessBuild Attribute でビルドを検知してメソッドを実行する方法

があります。
http://docs-jp.unity3d.com/Documentation/Manual/BuildPlayerPipeline.html
今回は C# を使いたかったので後者の方法を用います。

必要なもの

必要…というか、簡単に実装するために下記ライブラリを使います。

やること

Unitiy プロジェクトの任意の場所に "Editor" フォルダーを作成し、その中に上記ライブラリと以下のコードを追加します。

postprocessbuild.png

CustomPostProcessor.cs
using UnityEngine;
using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.XCodeEditor;
using MiniJSON;

/// <summary>
/// Unityのビルド後に実行する処理(XCodeのプロジェクト設定など)
/// </summary>
public static class CustomPostProcessor
{
    /// <summary>
    /// post process build event.
    /// </summary>
    /// <param name="target">Target(iPhone/Androidなど)</param>
    /// <param name="path">出力先のパス(ビルド時に指定するパス)</param>
    [PostProcessBuild (100)]
    public static void OnPostProcessBuild (BuildTarget target, string path)
    {
        if (target == BuildTarget.iPhone) {
            PostProcessBuild_iOS (path);
        }
    }

    /// <summary>
    /// iOSのビルド設定自動化処理
    /// </summary>
    /// <param name="path">出力先のパス(ビルド時に指定するパス)</param>
    private static void PostProcessBuild_iOS (string path)
    {
        // XCode プロジェクトファイルの設定をする
        CreateModFile (path);
        ProcessXCodeProject (path);
    }

    /// <summary>
    /// Mod ファイルの作成
    /// </summary>
    /// <param name="path">出力先のパス(ビルド時に指定するパス)</param>
    private static void CreateModFile (string path)
    {
        Dictionary<string, object> mod = new Dictionary<string, object> ();

        List<string> patches = new List<string> ();
        List<string> librarysearchpaths = new List<string> ();
        List<string> folders = new List<string> ();
        List<string> excludes = new List<string> ();

        // libs
        List<string> libs = new List<string> ();

        // フレームワークサーチパス
        List<string> frameworksearchpaths = new List<string> ();

        // フレームワーク
        List<string> frameworks = new List<string> ();
        frameworks.Add ("QuartzCore.framework");
        frameworks.Add ("CoreImage.framework:weak");

        // files
        List<string> files = new List<string> ();

        // headerpaths
        List<string> headerpaths = new List<string> ();

        // ビルド設定
        Dictionary<string,List<string>> buildSettings = new Dictionary<string,List<string>> ();
        List<string> otherLinkerFlags = new List<string> ();
        otherLinkerFlags.Add ("-ObjC");
        buildSettings.Add ("OTHER_LDFLAGS", otherLinkerFlags);

        mod.Add ("group", "");
        mod.Add ("patches", patches);
        mod.Add ("libs", libs);
        mod.Add ("librarysearchpaths", librarysearchpaths);
        mod.Add ("frameworksearchpaths", frameworksearchpaths);
        mod.Add ("frameworks", frameworks);
        mod.Add ("headerpaths", headerpaths);
        mod.Add ("files", files);
        mod.Add ("folders", folders);
        mod.Add ("excludes", excludes);
        mod.Add ("buildSettings", buildSettings);

        // mod から projmods ファイルを生成する
        string jsonMod = Json.Serialize (mod);

        string file = System.IO.Path.Combine (path, "CustomXCode.projmods");

        if (File.Exists (file)) {
            File.Delete (file);
        }

        using (StreamWriter streamWriter = File.CreateText (file)) {
            streamWriter.Write (jsonMod);
        }
    }

    /// <summary>
    /// projmods ファイルの設定値を XCode プロジェクト設定へ反映する
    /// </summary>
    /// <param name="path">出力先のパス(ビルド時に指定するパス)</param>
    private static void ProcessXCodeProject (string path)
    {
        XCProject project = new XCProject (path);

        string[] files = System.IO.Directory.GetFiles (path, "*.projmods", System.IO.SearchOption.AllDirectories);

        foreach (string file in files) {
            project.ApplyMod ( System.IO.Path.Combine (Application.dataPath, file));
        }

        project.Save ();
    }
}

※このコードは以下の設定をする例です。必要に応じて書き換えてください。

  • Framework に QuartzCore.framework を Required で追加、CoreImage.framework を Optional で追加
  • Other Linker Flags に "-ObjC" を追加

注意事項

今回使った XCodeEditor-for-Unity というライブラリは最近更新されていないみたいで、もしかしたらうまく設定できない項目があるかもしれません。
その場合は、いい感じに書き換えて使用してください。