他社のiOSアプリのビルド方法（証明書・p12・.mobileprovision を受け取った場合）

# 概要
あなたが自社ではなく他社のiOSアプリを作る場合、大きく分けて２種類の方法があります。
- 自分のDeveloper Accountを他社に招待してもらう 
- ipaファイルだけを納品するため、証明書群を受け取る

## 自分のDeveloper Accountを招待してもらう  
他社のAppStoreConnectに招待してもらい、チームの一員としてApple Developer Accountを登録してもらいます。

Appleが想定しているのはおそらくこちらです。

## ipaファイルだけを納品するため、証明書群を受け取る
今回のお話はこちらです。
1. 他社の Apple Developer アカウントから各種証明書群を発行
2. 各種証明書群をメールなどで受け取る
3. 自分のローカル or CI でビルド → ipa(アプリバイナリ) を納品
4. 他社の Apple Developer アカウントがipaファイルをAppStoreにアップして公開

というのが大雑把な手順ですが、特に3.についてがこの記事のメインです。

例えばExample社からの仕事を受けて以下のファイルを受け取ります。

- YourCoolApp.cer
- YourCoolApp.p12 (今回は例としてpasswordは`abcde`とする)
- YourCoolApp_PushNotification.cer（プッシュ通知を使うなら）
- YourCoolApp_PushNotification.p12（プッシュ通知を使うなら）
- YourCoolApp.mobileprovision

これらのファイルを受け取って、これらの情報を元にipaファイルだけをビルドします。

# 証明書群だけを受け取ってからビルドする方法
ダブルクリックをぽちぽちやってキーチェーンに登録、というのはCIやCDに組み込む時に困ってしまいます。  
なので理解してターミナル経由で処理しましょう。
順番にやっていけば大丈夫です。落ち着いていきましょう。

- MacOS Sequoia
- Xcode 16.1

で検証しました。
## 各種証明書をキーチェーンにインポート
上記の5個のファイルは同一フォルダにあり、terminalで該当フォルダに移動しておいてください。

### YourCoolApp.cer
最初にアプリの証明書をインポートします。
公開鍵が誰の公開鍵であるかを証明するものです。（pemとかpubみたいなもの）

```bash
security import certificate.cer \
    -k ~/Library/Keychains/login.keychain-db \
    -A
```
:::note info
login.keychain-dbはキーチェーンアプリのログインの中身を示します。
古いMacOSではlogin.keychainでしたが、最近はこれが実体のファイルです。
:::

### YourCoolApp.p12 
これを実行することで、Xcodeのアプリ署名のTeamIDとして選択可能になります。

```bash
security import YourCoolApp.p12 \                                     
    -k ~/Library/Keychains/login.keychain-db \
    -P abcde \
    -T /usr/bin/codesign \
    -T /usr/bin/security -A
```
:::note info
abcde はあなたの貰ったp12ファイルのパスワードです。
また、`-A`オプションはあらゆるアプリに対するアクセス有効化なので行儀は悪いです。
:::

無事インポートできたか確認しましょう。

```bash
security find-identity -p codesigning ~/Library/Keychains/login.keychain-db
```
これであなたのDevelop向けの署名に混じってExample社っぽいApple Distribution(もしくはiOS Distribution)の記載が出ていればOKです。

例:`Apple Distribution: Example CORPORATION (GK76YI3MNC)`

### YourCoolApp_PushNotification.cer
これはプッシュ通知用の証明書です。プッシュ通知を使わない場合は不要です。

```bash
security import aps.cer \
    -k ~/Library/Keychains/login.keychain-db \
    -A
```

### YourCoolApp_PushNotification.p12
同じくプッシュ通知用の署名です。プッシュ通知を使わない場合は不要です。abcdeは同じく指定のパスワードに置き換えてください。
```bash
security import YourCoolApp_PushNotification.p12 \                  
    -k ~/Library/Keychains/login.keychain-db \
    -P abcde -A
```

無事プッシュ通知の署名が確認できているかは、このように確認しましょう。確認できていないと後でびっくりします。

com.example.yourcoolappの部分は実際のあなたのアプリに置き換えてください。

```bash
security find-certificate \
    -c "Apple Push Services: com.example.yourcoolapp" \
    -p ~/Library/Keychains/login.keychain-db
```
こんな感じの結果が流れていればOKです。  
```txt
-----BEGIN CERTIFICATE-----
ここにいっぱいBase64の文字列が1000文字くらいある
-----END CERTIFICATE-----
```
### YourCoolApp.mobileprovision
Xcode上でSigining & Capabilitiesを確認して
1. Automatically manage signingのチェックを外します。
2. Provisioning Profileの指定から、YourCoolApp.mobileprovision を指定します。

その後、TeamがUnknown Nameになったままが正常です。
（なぜならあなたはExample社のAppStoreConnect上には存在しないメンバーなので！！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40627/def8d286-f39c-9099-65ca-824e9ee0b75b.png)

# Archiveが通ることを確認する
新規のXcodeプロジェクトを作って上記の設定をしたあと
Xcode→Product→Archiveができることを確認しましょう。

このあと、Distribute Appとか出来ないですが、それが正常です。
一旦はArchiveが出来て、この画面が出ていれば問題ないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40627/624b52ae-7a90-2736-2df8-6b73597cdd7b.png)

:::note info 
実際のお仕事では、証明書だけもらって他社アプリをビルドすることをXcodeのGUIは想定していないので、後述するような`xcodebuild`コマンドを使ったCUIでビルドすることが多いです。

workspaceだとこんな感じです。
```bash
xcodebuild -workspace "$WORKSPACE_PATH" -scheme "SomeAppName" -configuration Release clean archive...Distribution" PROVISIONING_PROFILE_SPECIFIER="YourCoolApp"
```
:::



# ipaが作れることを確認する
↑の画面で右クリックしてShow in Finderをしてみると
`yourcoolapp yyyy-mm-dd, hh.mm.xcarchive`

みたいなファイルが見えます。
これに対して
xcodebuildのexportArchiveでipaファイルが生成できます。

```bash
xcodebuild -exportArchive -archivePath $PWD/build/App.xcarchive -exportPath $PWD/build/ -exportOptionsPlist $PWD/exportOptions.plist
```

- exportOptions.plistは自動生成が出来ないので開発環境向けなどで手動ビルドしてしまう https://qiita.com/uhooi/items/a17a5d0e5dd5a76191ac こんな感じ
- あるいはexportOptions.plistは手で全部書いてもなんとかなる https://gist.github.com/DanBodnar/020e7a10bc286dc3e5946e7ccc20dd7b 
- xcodebuildにexportOptions.plistを生成するオプションが生えて欲しいな


### exportOption補遺
他プロジェクトの情報を参考にする場合は以下に注意
- Development / AdHoc / Enterprise / App Store
のどれを使うかで method が変わること。
- uploadSymbols (trueにしておくべき)
- teamIDなどプロジェクト固有のものを書き換える


## 証明書インポートに関するトラブルシューティング

インポート時やアーカイブ時にエラーが出てビルドできない場合、以下をチェックしましょう。

### 1. security import のエラーいろいろ
#### Passphrase error
```bash
security: SecKeychainItemImport: MAC verification failed during PKCS12 import (wrong password?)
```
p12ファイルのパスワードが間違っている可能性があります。
もう一度正しいパスワードを確認して指定しましょう。

#### “MAC verification failed” のようなメッセージ
p12ファイル自体が壊れている、あるいはパスワードなしのp12に誤ってパスワード付きで実行している場合などに起きることがあります。
Example社からファイルを再度もらうか、パスワードの有無を再確認してください。

#### “No such file or directory”
単純にファイルパスの指定ミスです。
ターミナル上で ls -l してファイル名やパスが合っているか再度確かめましょう。

:::note warning 
時々、ファイル拡張子が .p12 になっているのに中身が .pem や .cer だった…というケースもあります。拡張子と実ファイル形式が食い違うとインポートでエラーになるのでご注意ください。 
:::

### 2. プロビジョニングプロファイルとの不一致
“No matching provisioning profiles found”
XcodeでArchiveしようとすると、このようなエラーが出ることがあります。

プロビジョニングファイルのTeam IDと、インポートした証明書のTeam IDが一致していない
もしくは証明書の有効期限が切れている
Provisioning Profile自体が古い（期限切れ）など
これらの場合、Example社に連絡して 新しい証明書 と 新しい .mobileprovision を発行してもらいましょう。

あとはXcodeのmanaged auto signingのチェックをオンにしたまま、ということもあります。

### 3. 実機デバッグしたいのに端末が登録されていない
今回は「他社のアカウントでAd Hoc・Distribution用の証明書をもらっているだけ」のケースです。

そのため、Example社のプロビジョニングに自分のデバイスUDIDが入っていないと実機インストールができません。

実機テストが必要な場合は、Example社にUDIDを伝えて .mobileprovision を再度発行してもらいましょう。

あるいは自分のApple Developer AccountでDevelopment用のプロジェクトを別途作る方法もあり。記事中でも少し触れましたが、そちらで実機確認します。

## CI/CDへの組み込みを見据えて
今回はGUIの操作を極力使わずterminal上で証明書や署名を行うようにしています。

これは何が嬉しいかというとGithub ActionなどのCIシステムに移植するのが容易だということです。

```yml
name: iOS Build (ExampleApp)

on:
  push:
    branches: [ "main" ]

jobs:
  build:
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v4

      # ① 証明書やプロビジョニングファイルをリポジトリに含めるのは危険なので、
      #    通常はGitHub SecretsやEncrypted Filesなどを用います。
      #    ここでは単純化のために「Base64エンコードした.p12ファイルをSecretに格納」
      #    している例を示します。
      - name: Decode & Import Certificates
        run: |
          echo "$P12_BASE64" | base64 --decode > /tmp/YourCoolApp.p12
          echo "$PROVISION_BASE64" | base64 --decode > /tmp/YourCoolApp.mobileprovision

          security import /tmp/YourCoolApp.p12 \
            -k ~/Library/Keychains/login.keychain-db \
            -P $P12_PASSWORD \
            -T /usr/bin/codesign \
            -T /usr/bin/security \
            -A

          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp /tmp/YourCoolApp.mobileprovision \
             ~/Library/MobileDevice/Provisioning\ Profiles/

      # ② ビルド & アーカイブ
      - name: Build & Archive
        run: |
          xcodebuild clean \
            -project YourCoolApp.xcodeproj \
            -scheme YourCoolApp \
            -configuration Release

          xcodebuild archive \
            -project YourCoolApp.xcodeproj \
            -scheme YourCoolApp \
            -configuration Release \
            -archivePath $GITHUB_WORKSPACE/build/YourCoolApp.xcarchive

      # ③ IPAファイルをエクスポート
      - name: Export IPA
        run: |
          xcodebuild -exportArchive \
            -archivePath $GITHUB_WORKSPACE/build/YourCoolApp.xcarchive \
            -exportPath $GITHUB_WORKSPACE/build/ \
            -exportOptionsPlist $GITHUB_WORKSPACE/exportOptions.plist

      # ④ 作られたIPAファイルをArtifactsとして保存
      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: YourCoolApp.ipa
          path: build/*.ipa
```

- Secret管理: .p12 や .mobileprovision を直接リポジトリに含めず、Base64化したファイルをGitHub Secretsに登録し、ジョブ内で `base64 --decode` して使うやり方がポピュラー
- Keychain登録: ローカルとほぼ同じ手順でOKですが、CI上では自動ログインキーチェーンや一時的に作ったカスタムキーチェーンを使う場合もあります。確認しておきましょう。
- exportOptionsPlist: 同様にリポジトリにチェックインするか、やはりSecret化・パラメータ化することが多いです。

こうすれば、GitHub Actionsが自動でビルド→IPAファイルをArtifactsとして出力してくれるので、Example社にIPAを渡すのもスムーズになります。

:::note info 
BitriseやJenkins、CircleCI等でも同じ流れで「秘密鍵・証明書の登録 → xcodebuild」をすればOKです。
それぞれのCIサービスごとに専用プラグインやUIがあるので、適宜活用しましょう。 
:::


Appleの証明書自体の概要をつかむには以下がおすすめです。
https://qiita.com/bl-lia/items/c6ec88020d526cdb454c