18
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UnityのiOSビルドをコマンドラインから行う (Mac用)

Last updated at Posted at 2019-06-23

前回はAndroidのビルドを行いましたが、今回はiOSビルドです。

コマンドラインでビルドを行った後、Archive処理を進め、
最終的にipaファイルを生成するのが目的となります。

Debugビルド & プロビジョニングを自分で設定するパターンで進めていきます。

Unityだと、Xcodeのプロジェクトビルドまでしか行われず、
Xcodeのビルドは別途自分で書かないといけないみたいので、
Anrdroidと比べて、結構手数が多くなります。

環境

Mac : 10.14.5 (Mojave)
Unity : 2018.3.0f2
Xcode : 10.2.1

unity側でのビルド手続き

Androidでは、直接Unity側に成果物のパスを指定してましたが
iOSの場合、Xcodeビルド時に、成果物のパスが必要になる為、
コマンドラインからUnityにパスを受け渡せる様にしています。

GetParameterFrom関数にargの引数を指定して続くパラメータを取得しています。
(最近swiftでの開発が多かったので、関数名の付け方とかがちょっとswift脳になってます・・・

stringのOptionalほしい・・
(C# 8.0からクラスのオプショナルも対応するらしいです

Builder.cs
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public static class Builder
{
    public static void iOSBuild()
    {

        var outputDirKey = "-output-dir";

        var paths = GetBuildScenePaths();
        var outputDir = GetParameterFrom(key: outputDirKey);
        var buildTarget = BuildTarget.iOS;
        var buildOptions = BuildOptions.Development;

        Debug.Assert(!string.IsNullOrEmpty(outputDir), $"'{outputDirKey}'の取得に失敗しました");

        var buildReport = BuildPipeline.BuildPlayer(
            paths.ToArray(),
            outputDir,
            buildTarget,
            buildOptions
        );

        var summary = buildReport.summary;

        if (summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
        {
            Debug.Log("Success");
        }
        else
        {
            Debug.LogError("Error");
        }
    }

    private static IEnumerable<string> GetBuildScenePaths()
    {
        var scenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
        return scenes
            .Where((arg) => arg.enabled)
            .Select((arg) => arg.path);
    }

    private static string GetParameterFrom(string key)
    {
        var args = System.Environment.GetCommandLineArgs();
        var index = args.ToList().FindIndex((arg) => arg == key);
        var paramIndex = index + 1;

        if (index < 0 || args.Count() <= paramIndex)
        {
            return null;
        }

        return args[paramIndex];
    }
}

シェルスクリプト (Unityビルド)

Xcodeビルドもあるため、シェルスクリプトが長めになるので、
UnityビルドとXcodeビルドでシェルスクリプトファイルを分割しています。

unityiOSBuild.shxcodeBuild.sh両ファイルとも、
Unityのプロジェクトフォルダ直下に作成してください。

-output-dirでXcodeプロジェクトの出力先を指定してます。

また unityのビルドが完了したら引き続きPROJECT_DIR=$PROJECT_DIR sh xcodeBuild.sh
Xcodeのビルドに処理を引き継いでいます。

ちなみに、変数は明示的に指定しないと引き継げないみたいです。
(なんかもっとスマートなやり方がありそうな気もしますが・・・

unityiOSBuild.sh
#!/bin/bash

UNITY_APP_PATH="/Applications/Unity/Unity.app/Contents/MacOS/Unity"
UNITY_PROJECT_PATH="./"
UNITY_BUILDE_NAME="Builder.iOSBuild"
UNITY_LOG_PATH="./build/iOS/build.log"
PROJECT_DIR="./build/iOS"

$UNITY_APP_PATH -batchmode \
    -quit \
    -projectPath $UNITY_PROJECT_PATH \
    -executeMethod $UNITY_BUILDE_NAME \
    -logfile $UNITY_LOG_PATH \
    -output-dir $PROJECT_DIR

if [ $? -eq 1 ]; then
    echo "error!! check logfile: ${UNITY_LOG_PATH}"
    exit 1
fi

echo "unity build success!!"
PROJECT_DIR=$PROJECT_DIR sh xcodeBuild.sh

シェルスクリプト (Xcodeビルド)

xcodebuildのシェルスクリプトです。

最終的にほしいのはipaファイル

一旦Archiveファイル(xcarchive)を生成し、それを元に
ipaファイルを生成します。

ただし、ビルドするためにprovisioning profileUUIDが必要となり、
ipaファイルの作成にExportOptions.plistが必要となります。

provisioning profile のUUID

こちらはプロビジョニングプロファイルのファイルをテキストエディタ等で開くことで確認できます。

中身はXml形式で記述されているので keyがUUIDの部分のstringから値を確認して
PROVISIONING_PROFILEに指定してください。

XXX.mobileprovision
	<key>UUID</key>
	<string>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</string>

ExportOptions.plist

このplistはipaファイルをビルドする際の設定情報を記述するファイルになります。
正直記述するのが面倒なので、Xcodeのプロジェクトファイルができたら、
一旦XcodeからArchiveビルドを行ってipaファイルを吐き出しましょう。

そうすると、ipaファイルが生成されたフォルダ内にExportOptions.plistが生成されてるので
それをUnityのプロジェクトフォルダ直下にコピペって来るだけでOKです。

スクリプト

以下、xcodeBuildのビルド手続きです。
PROJECT_DIRunityiOSBuild.shより引き継いでいます。

xcodeBuild.sh
#!/bin/bash

SCHEME="Unity-iPhone"
PROJECT_PATH="${PROJECT_DIR}/${SCHEME}.xcodeproj"
ARCHIVE_FILE="${SCHEME}.xcarchive"
ARCHIVE_DIR="${PROJECT_DIR}/archive"
ARCHIVE_PATH="${ARCHIVE_DIR}/${ARCHIVE_FILE}"
IPA_DIR="${ARCHIVE_DIR}/output_ipa"
EXPORT_OPTIONS_PLIST="ExportOptions.plist"
PROVISIONING_PROFILE="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

mkdir -p $ARCHIVE_PATH

# ARCHIVE
xcodebuild -project $PROJECT_PATH \
    -scheme $SCHEME \
    archive -archivePath $ARCHIVE_PATH \
    PROVISIONING_PROFILE=$PROVISIONING_PROFILE

# ipaファイルの作成
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH \
    -exportPath $IPA_DIR \
    -exportOptionsPlist $EXPORT_OPTIONS_PLIST \
    PROVISIONING_PROFILE=$PROVISIONING_PROFILE

ターミナルから実行

以下コマンドをターミナルから実行します。
Unityが起動した状態で行うと、うまくビルドができないので、
Unityは終了させた状態で実行します。

ターミナルから実行
sh unityiOSBuild.sh

実行後正常に完了したら、ipaファイルがプロジェクトフォルダは以下の
./build/iOS/archive/output_ipaに生成されているはずです。

ipaファイルをXcodeから実機にインストールして動作を確認しましょう。

github

補足

ちなみに、ExportOptions.plistの中身はこんな感じでした。
(認証情報が含まれるので一部 !!! で囲んで伏せ字にしてます

ExportOptions.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>compileBitcode</key>
	<false/>
	<key>method</key>
	<string>ad-hoc</string>
	<key>provisioningProfiles</key>
	<dict>
		<key>!!! Bundle Identifer !!!</key>
		<string>!!! code signing identifier !!!</string>
	</dict>
	<key>signingCertificate</key>
	<string>iPhone Distribution</string>
	<key>signingStyle</key>
	<string>manual</string>
	<key>stripSwiftSymbols</key>
	<true/>
	<key>teamID</key>
	<string>!!! teamID !!!</string>
	<key>thinning</key>
	<string>&lt;none&gt;</string>
</dict>
</plist>
18
10
2

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
18
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?