Codemagicを使ってUnity iOSアプリをApp Store Connectに公開する方法

![codemagic-blog-header-mix-publishing-unity-to-app-store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2028491/92319514-6cea-7743-51bf-33fd453e3826.png)
[Unity](https://unity.com/)は、デスクトップ、コンソール、モバイルデバイス用の2Dおよび3Dゲームを作成するための人気のあるクロスプラットフォームゲームエンジンです。これは、モバイルゲームやAR（拡張現実）モバイルアプリ、UnityとFlutterやReact Nativeを組み合わせたハイブリッドアプリの構築に最適な選択肢の一つです。

本記事では、Codemagic CI/CDを使用してUnity iOSアプリをビルド、コード署名、App Store Connectに直接公開し、そこからTestFlightを使用してテスターや関係者にアプリを配布したり、App Storeにリリースを公開する方法についてご説明いたします。Codemagicでは、Xcodeをローカルにインストールすることなく、UnityのiOSアプリをビルドできることは特筆に値します。しかも、Macを持っている必要すらありません！

本記事では、Unityのプロジェクト自体には注目しません。その代わり、構築と公開の各ステップを踏みます。以下のような感じです：

- CodemagicでUnityプロジェクトをビルドし、App Store Connectに公開するための前提条件をご説明いたします。
- 環境変数の定義やYAMLファイルの調整など、Codemagicのセットアップを行います。
- 最後に、Xcodeプロジェクトをビルドし、公開するための準備をするために、いくつかのC#スクリプトを追加します。

## CodemagicでUnity iOSアプリをビルドして公開するための前提条件

まず、この記事のすべてのステップを実行できるようにするために、以下のものをご用意ください：

- Unity PlusまたはPro [ライセンス](https://store.unity.com/compare-plans)。
- 有効な[Apple Developer Program](https://developer.apple.com/programs/)のメンバーシップ。
- 自動コード署名用の[App Store Connect APIキー](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api)を作成するためのApple Developer Programの管理者権限。
- Gitベースのバージョン管理システムにチェックインしたUnityのプロジェクト。
- Unity SDKが事前インストールされたmacOS VMインスタンスにアクセスできるCodemagicの**チーム**。この手配は、Codemagic（[こちら](https://codemagic.io/contact/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)）までご連絡ください。

{{< contact-form title="Unity SDKでのCodemagic VMへのアクセスを要求する" subtitle="フォームに入力してCodemagicソリューションエンジニアへお問い合わせください" >}}

## UnityプロジェクトをCodemagicに追加

Codemagicにプロジェクトを追加する最も簡単な方法は、Gitプロバイダーを経由することです。[GitHub](https://github.com/)、 [Bitbucket](https://bitbucket.org/)、[GitLab](https://about.gitlab.com/) などのGitソース管理サービスにプロジェクトを追加し、以下の手順でCodemagicを開始します：

1. [Codemagic](https://codemagic.io/login/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)にログインします。新規ユーザー様の場合、[サインアップ](https://codemagic.io/signup/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)してください。

2. [設定](https://codemagic.io/settings/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)の統合（Integrations）から、UnityプロジェクトをアップロードしたGitプロバイダーに接続します。アプリをアップロードしたリポジトリにアクセス許可が与えられていることをご確認ください。

3. [アプリケーション](https://codemagic.io/apps/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)ページに移動し、**アプリケーションの追加（Add application）**をクリックします。
   
   ![](https://blog.codemagic.io/uploads/2022/01/unity-ios-add-application.png)

4. Unity SDKインスタンスへのアクセス権が付与されているチームを選択します。アクセス権がない方は、Codemagicにお問い合わせください（[こちら](https://codemagic.io/contact/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)）。

5. **Gitプロバイダー**を選択します。
   
   ![](https://blog.codemagic.io/uploads/2022/01/unity-ios-connect-repository.png)

6. **次に、統合を承認する（Authorize integration）**をクリックして、Codemagicを承認します。選択したGitプロバイダーの承認がお済みの場合は、その代わりに**次に、レポジトリを選択（Next: Select repository）**を選択してください。
   
   > **GitHub**をGitプロバイダーとして使用している場合は、リポジトリを選択する前に追加ステップを1つ実行する必要があります。**GitHubアプリをインストール（Install GitHub App）**をクリックして統合をセットアップします。GitHubアプリ統合の設定についての詳細は、[こちら](https://docs.codemagic.io/getting-started/adding-apps-from-custom-sources/#configuring-the-github-app-integration/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)をご覧ください。

7. ここで、ドロップダウンメニューからリポジトリを選択し、プロジェクトタイプとして **Unityアプリ**を選択します。次に、**終了して、アプリケーションを追加（Finish: Add application）**をクリックします。

8. プロジェクトの設定に移ります。デフォルトでは**codemagic.yaml**タブが選択されます。
   
### Unityの認証情報をセキュアな環境変数としてCodemagicに追加します。

Unityのシリアルナンバーは、CodemagicのビルドマシンでUnityをアクティベートするために使用され、iOSプロジェクトをエクスポートできるようになります。そして、ライセンスはYAML設定の`publishing`セクションで返されるため、ビルドステップの1つが失敗してもライセンスは返されます。 

`UNITY_SERIAL`、`UNITY_USERNAME`、`UNITY_PASSWORD`という名前の環境変数を含む、“unity”という環境変数グループを作成する必要があります。この環境変数群は、この後のステップでご説明する **codemagic.yaml** 設定ファイルにインポートされます。 

Codemagicで必要な環境変数を以下のように作成します：

1. チームを使用している場合は、**チーム > チーム名**をクリックし、**グローバル変数とシークレット**をクリックします。そうでない場合は、**環境変数（Environment variables）**タブをクリックして、アプリケーションレベルで環境変数を追加できます。

2. `UNITY_SERIAL`という変数を作成し、その値をあなたのUnityシリアル番号に設定します。**グループの選択**ドロップダウンに`unity`と入力し、**“unity”グループの作成（Create “unity” group）**ボタンをクリックします。値を暗号化するために、変数を**セキュア(secure)**とマークし（マークは実際には、ここと以下のすべてのケースでデフォルトでチェックされています）、**追加**ボタンをクリックします。

3. `UNITY_USERNAME`という名前の変数を作成します。値を、Unity IDで使用している**メールアドレス**に設定し、それを“unity”グループに追加します。値を暗号化するために、これを**セキュア（secure）**とマークし、**追加**ボタンをクリックします。

4. `UNITY_PASSWORD`という名前の変数を作成します。値をUnity ID**パスワード**に設定し、それを“unity”グループに追加します。値を暗号化するために、これを**セキュア**とマークし、**追加**ボタンをクリックします。

    ![](https://blog.codemagic.io/uploads/2022/01/unity-ios-environment-variable-group-unity.png)

Unityのインストール先を定義する環境変数 `UNITY_HOME` は、ビルドマシン上ですでに設定されていることにご注意ください。macOSの場合は[こちら](https://docs.codemagic.io/specs/versions4-unity/#unity-2020320f1)、Windowsの場合は[こちら](https://docs.codemagic.io/specs/versions-windows/#unity-2020323f1/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)で場所を確認できます。

### UnityアプリのiOSコード署名を自動的に行うための環境変数を追加する

Codeamgicでは、iOS向けUnityアプリを**自動でコード署名**できます。そのためには、以下の環境変数を“ios_credentils”という環境変数グループに作成する必要があります：

`APP_STORE_CONNECT_KEY_IDENTIFIER`、`APP_STORE_CONNECT_ISSUER_ID`、`APP_STORE_CONNECT_PRIVATE_KEY`、 `CERTIFICATE_PRIVATE_KEY`。 

そこで、同じタブにとどまり、別の変数グループを作成する必要があります。
   
1. `APP_STORE_CONNECT_KEY_IDENTIFIER` という変数を作成し、その値をApp Store Connect APIの**キー識別子（Key Identifier）**に設定します。**グループの選択**ドロップダウンに`ios_credentials`と入力し、** "ios_credentials"グループの作成**ボタンをクリックします。値を暗号化するために、変数を**セキュア**とマークし、**追加**ボタンをクリックします。

2. `APP_STORE_CONNECT_ISSUER_ID`という名前の変数を作成します。値をApp Store Connect APIの**発行者（Issuer）ID**に設定し、それを“ios_credentials”グループに追加します。値を暗号化するために、変数を**セキュア**とマークし、**追加**ボタンをクリックします。

3. `APP_STORE_CONNECT_PRIVATE_KEY`という名前の変数を作成します。App Store Connect APIの**秘密鍵（Private Key）(.p8)**に値を設定し、それを“ios_credentials”グループに追加します。値を暗号化するために、変数を**セキュア**とマークし、**追加**ボタンをクリックします。

4. `CERTIFICATE_PRIVATE_KEY`という名前の変数を作成し、その値を**iOS配信証明書の秘密鍵（iOS Distribution Certificate private key）**に設定します。それを“ios_credentials”グループに追加します。値を暗号化するために、変数を**セキュア**とマークし、**追加**ボタンをクリックします。

    ![](https://blog.codemagic.io/uploads/2022/01/unity-ios-environment-variable-group-ios.png)

> App Store Connect APIキーの作成と必要な環境変数の値の取得方法については、iOSアプリの署名に関するドキュメントをご参照ください（[こちら](https://docs.codemagic.io/yaml-code-signing/signing-ios/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)）。

### codemagic.yamlを使用してUnity iOSアプリ用にCodemagicを設定する

Codemagicでは、WindowsとmacOSの両マシンでUnity SDKをご提供しておりますが、今回はiOS向けのアプリを作る必要があるため、macOSのマシンを使用することにいたします。YAMLを使ってビルドを設定するには、Unityプロジェクトに移動し、ルートディレクトリ内に `codemagic.yaml` というファイルを新規に作成します。

以下のテンプレートをファイルに追加します：

```yaml
workflows:
  my-workflow:
    name: Workflow name
    max_build_duration: 120
    environment:
      groups:
        - ...
      vars:
        - ...
        
    scripts:
      - ...
    artifacts:
      - ...
    publishing:
      - ...
```

これはCodemagicでアプリを構築するための基本的なワークフローテンプレートです。詳しくは、[ドキュメント](https://docs.codemagic.io/yaml/yaml-getting-started/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)をご覧ください。

`publishing`セクションでは、App Store Connectにアプリを公開し、貴社内のApp Store Connectユーザー様によるテストに利用できるようにすることにご注意ください。社内グループ（Internal Group）を作成し、アプリを配布したいテスターを追加するだけです。 

アプリを外部のTestFlightユーザーに配布したり、App Store Reviewに直接提出する必要がある場合、その設定方法は[こちら](https://docs.codemagic.io/yaml-publishing/distribution/#app-store-connect)に記載されております。App Store Connectへのアプリ公開については、[こちら](https://blog.codemagic.io/publish-to-app-store-connect-with-codemagic/?utm_source=qiita&utm_medium=referral&utm_campaign=flutter_distribution&utm_content=japanese_lang)の記事もご覧ください。

.ipaを生成し、App Storeに公開するには、以下のステップでワークフローを変更します：

1. `ワークフロー`セクションで、適切なワークフロー名を定義します：
   
   ```yaml
   workflows:
      -unity-ios-release-workflow:
         name: Unity iOS release workflow
         max_build_duration: 120
   ```

   > なお、この時点ではinstance_typeプロパティは定義しない方がよいです。Unity SDKを含むMac Proインスタンスへのアクセスが許可されている場合、デフォルトではすでに`mac_pro_unity`に設定されており、codemagic.yamlファイルでは設定する必要は**ありません**。

2. 先ほど`groups` セクションで作成した環境変数グループをインポートします：
   
   ```yaml
   environment:
      groups:
         - unity
         - ios_credentials
   ```

3. `vars`セクションに以下の環境変数を設定します：
  
   ```yaml
   vars:
     UNITY_BIN: /Applications/Unity/Hub/Editor/2020.3.20f1/Unity.app/Contents/MacOS/Unity
     BUILD_SCRIPT: BuildIos 
     UNITY_IOS_DIR: ios
     XCODE_PROJECT: "Unity-iPhone.xcodeproj"
     XCODE_SCHEME: "Unity-iPhone"
     BUNDLE_ID: <BUNDLE_ID>
     APP_STORE_APP_ID: <APPLE_ID>
   ```
  
   > 角括弧を適切な値に置き換えます。`バンドルID`と`アップルID`は、[App Store Connect](https://appstoreconnect.apple.com/login) > アプリ > 一般 > アプリ情報で確認できます。

4. `scripts`セクションで、macOSキーチェーンを初期化します：

   ```yaml
   scripts:
     - name: Initialize macOS keychain
       script: | 
         keychain initialize  
    ```

5. 以下のスクリプトでUnityをアクティベートします：
   
   ```yaml
   - name: Activate Unity License
     script: | 
       $UNITY_BIN -batchmode -quit -logFile -serial ${UNITY_SERIAL?} -username ${UNITY_USERNAME?} -password ${UNITY_PASSWORD?}
   ```

6. Xcodeプロジェクトをエクスポートします
   ```yaml
   - name: Build the Xcode project
     script: | 
       $UNITY_BIN -batchmode -quit -logFile -projectPath . -executeMethod BuildScript.$BUILD_SCRIPT -nographics
   ```
   
7. iOSの署名ファイルを取得します：

   ```yaml
   - name: Fetch signing files
     script: | 
       app-store-connect fetch-signing-files $BUNDLE_ID --type IOS_APP_STORE
   ```
8. キーチェーンに証明書を追加します：

   ```yaml
   - name: Add certificates to default keychain
     script: | 
       keychain add-certificates
   ```

9. Xcodeにプロビジョニングプロファイルを追加します：

   ```yaml
   - name: Set up code signing settings on Xcode project
     script: | 
       xcode-project use-profiles
   ```

10. ビルド番号をインクリメントします：

    ```yaml
    - name: Increment build number
      script: | 
        cd ios && agvtool new-version -all $(($(app-store-connect get-latest-testflight-build-number "$APP_STORE_APP_ID") + 1))
    ```

11. .ipaをビルドします：

    ```yaml
    - name: Build ipa for distribution
      script: | 
        xcode-project build-ipa --project "$UNITY_IOS_DIR/$XCODE_PROJECT" --scheme "$XCODE_SCHEME"
    ```

12. 生成された.ipaを取得するために、`artifacts`（成果物）のパスを以下のように更新します：
    
    ```yaml
    artifacts:
      - build/ios/ipa/*.ipa
    ```
13. Unityのライセンスを返すように`publishing`セクションを更新し、App Store Connectに公開します：

    ```yaml
      publishing:
        scripts:
          - name: Deactivate Unity License
            script: $UNITY_BIN -batchmode -quit -returnlicense -nographics
        app_store_connect:            
          api_key: $APP_STORE_CONNECT_PRIVATE_KEY         
          key_id: $APP_STORE_CONNECT_KEY_IDENTIFIER
          issuer_id: $APP_STORE_CONNECT_ISSUER_ID
    ```

これで`codemagic.yaml`ファイルの設定は完了です。全体像を確認したい場合は、[このブログ記事のサンプルプロジェクト](https://github.com/codemagic-ci-cd/codemagic-sample-projects/tree/main/unity/unity-demo-project)のルートフォルダに、Unityアプリ用の`codemagic.yaml`ファイルの実用例があります。あとは、このファイルをコミットしてGitプロバイダーに追加するだけです。

## Unityプロジェクトにビルドスクリプトを追加する

Xcodeプロジェクトをヘッドレスモードでビルドするには、Unityのビルドスクリプトが必要です。では、用意しましょう。

ローカルマシンでUnityを開き、アセット/エディタ（Assets/Editor）のプロジェクトエクスプローラーに**ビルド（Build）**というC#スクリプトを新規に追加します。 

以下をファイルに追加します：
   
```c#
using System.Linq;
using System;
using UnityEditor;
using UnityEngine;

public static class BuildScript
{

    [MenuItem("Build/Build iOS")]
    public static void BuildIos()
    {
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.locationPathName = "ios";
        buildPlayerOptions.target = BuildTarget.iOS;
        buildPlayerOptions.options = BuildOptions.None;
        buildPlayerOptions.scenes = GetScenes();

        Debug.Log("Building iOS");
        BuildPipeline.BuildPlayer(buildPlayerOptions);
        Debug.Log("Built iOS");
    }

    private static string[] GetScenes()
    {
        return (from scene in EditorBuildSettings.scenes where scene.enabled select scene.path).ToArray();
    }

}
```

`BuildIos`メソッドは、Xcodeプロジェクトを`ios`というフォルダにエクスポートするために使用されます。また、メニュー項目もUnity UIに追加され、**ビルド** > **iOSのビルド**をクリックすると、Xcodeプロジェクトをエクスポートできるようになります。

## アプリが暗号化を使用しているかどうかを宣言するビルド後のスクリプトを追加

UnityアプリをApp Store Connectに公開する際、アプリに暗号化を使用しているかどうか尋ねられます。新しいバージョンを公開するたびに手動でこの質問に答えたくない場合は、Unityに別のスクリプトを追加して、Xcodeプロジェクトのルートにある`Info.plist`ファイルに`ITSAppUsesNonExemptEncryption`というキーを設定し、アプリで暗号化を使用していない場合は値を**NO**に、使用している場合は**YES**に設定すると、自動的にこの質問に答えることができるようになります。

> 暗号化のエクスポート規制の遵守について、詳しくは[こちら](https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations)をご覧ください。 

必要なビルド後のスクリプトを追加するには、Unityを開き、アセット/エディタディレクトリのプロジェクトエクスプローラーに**PostProcessing**（後処理）という新しいC#スクリプトを追加し、そこに以下を追加します：

```c#
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;

public class IosBuildPostprocessor
{

    [PostProcessBuild(1)]
    public static void EditPlist(BuildTarget target, string path)
    {
        if (target != BuildTarget.iOS)
            return;


        string plistPath = path + "/Info.plist";
        PlistDocument plist = new PlistDocument();
        plist.ReadFromFile(plistPath);

        PlistElementDict rootDict = plist.root;

        // Add ITSAppUsesNonExemptEncryption to Info.plist
        rootDict.SetString("ITSAppUsesNonExemptEncryption", "false");


        File.WriteAllText(plistPath, plist.WriteToString());
    }
}
```

このスクリプトは、XcodeプロジェクトがUnityからエクスポートされた後に実行されます。

## UnityでiOSのバンドル識別子を設定する

Xcodeプロジェクトをビルドする前に、iOSアプリケーションのバンドルIDを設定する必要があります。 

これは以下のように行えます：

1. Unityを開き、**ファイル** > **ビルド設定**を実行します。
2. iOSが選択されたプラットフォームとなっていることを確認し、**プレイヤー設定**ボタンをクリックします。
3. **その他の設定**セクションを展開します。
4. **ID**セクションで、**デフォルトのバンドル識別子をオーバーライドする（Override Default Bundle Identifier）**オプションにチェックを入れます。
5. Apple Developer Programアカウントで使用している識別子名と一致するように、**バンドル識別子（Bundle Identifier）**を設定します。
6. **バージョン**を0.0.1などご希望通りに設定します。Codemagicでは自動的にビルド番号をインクリメントするため、この設定は0にしたままでもいいです。

### 最初のビルドを実行

Gitプロバイダーに行ったすべての変更をコミットするのを忘れないでください。

YAMLファイルを使用してUnity iOSアプリのビルドを開始するには、Codemagicのプロジェクトページに移動し、**最初のビルドを開始する（Start your first build）**をクリックします。ワークフローを選択し、**新規ビルドを開始（Start new build）**をクリックしてビルドプロセスを開始します。プロジェクトの規模にもよりますが、数分から数十分かかる場合があります。

## 結論

おめでとうございます！　これで、Unity iOSアプリがビルドされ、App Store Connectに公開されるはずです。しかも、すべてのプロセスが自動化されました！　もう、手動でのビルド、コード署名、アップロードに悩まされる必要はありません！　また、Codemagicを使うと、Unity iOSアプリをビルドするのに、Macを所持したりXcodeをインストールしたりする必要もありません。

本記事では、Codemagicを使ってUnity iOSアプリをビルドして、App Store Connectに公開する方法についてご紹介いたしました。Unity iOSアプリをビルドするための完全な`codemagic.yaml`設定ファイルは[こちら](https://github.com/codemagic-ci-cd/codemagic-sample-projects/tree/main/unity/unity-demo-project) にあります。Android向けのUnityアプリの構築については、こちらの[ドキュメント](https://docs.codemagic.io/yaml-quick-start/building-a-unity-app/)をご参照ください。

CodemagicでUnityアプリをビルドして公開するのは、非常にシンプルで簡単なはずです（記事は長めだったかもしれませんが）。ですが、もしどこかで行き詰まった場合、いつでも私たちがお助けいたします。例えばSlackで、一つ一つのご質問にお答えするように努めております。また、プロフェッショナルプランかエンタープライズプランをご利用の方は、アプリ内のチャットで、当社のエキスパートがいつでもご対応させていただきます。

楽しんでビルドしましょう！