LoginSignup
36
33

More than 5 years have passed since last update.

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

Posted at

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 というライブラリは最近更新されていないみたいで、もしかしたらうまく設定できない項目があるかもしれません。
その場合は、いい感じに書き換えて使用してください。

36
33
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
36
33