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# を使いたかったので後者の方法を用います。
必要なもの
必要…というか、簡単に実装するために下記ライブラリを使います。
-
XCodeEditor-for-Unity
https://github.com/dcariola/XCodeEditor-for-Unity
やること
Unitiy プロジェクトの任意の場所に "Editor" フォルダーを作成し、その中に上記ライブラリと以下のコードを追加します。
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 というライブラリは最近更新されていないみたいで、もしかしたらうまく設定できない項目があるかもしれません。
その場合は、いい感じに書き換えて使用してください。