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

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

More than 5 years have passed since last update.

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

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
ユーザーは見つかりませんでした