ビルドを App Store に送る道

1 編では MAS ビルドターゲットを、2 編では 2 つのチャネルを分ける設定ファイルとコード分岐を作成しました。これで FocusTimer MAS ターゲットは App Store に出せる形になりました。

この最終編では、そのビルドを App Store Connect にアップロードする道を整え、2 つのチャネルが今後も壊れないよう検証する方法も扱い、シリーズを締めくくります。

1 編・2 編と同様、FocusTimercom.example.FocusTimer.mas、Team ID ABCDE12345 などはすべてサンプル値です。

ステップ 1 — アップロード用 ExportOptions-MAS.plist

直接配布シリーズで、アーカイブを配布用にエクスポートする際、xcodebuild -exportArchive コマンドが ExportOptions.plist を読み込むと説明しました。MAS チャネルには別のエクスポート設定ファイルが必要です。

プロジェクトのリリースディレクトリに ExportOptions-MAS.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>method</key>
    <string>app-store</string>
    <key>destination</key>
    <string>upload</string>
    <key>signingStyle</key>
    <string>automatic</string>
    <key>teamID</key>
    <string>ABCDE12345</string>
</dict>
</plist>

各キーの意味は次のとおりです。

  • method = app-store — このビルドを Mac App Store チャネル用としてエクスポートするという意味です。直接配布チャネルの developer-id と対比されます。
  • destination = uploadxcodebuild -exportArchive がエクスポートした成果物をそのまま App Store Connect にアップロードします。以前のように Transporter や別のアップロードツールを経由する必要はありません。
  • signingStyle = automatic — Xcode が Mac App Store 用のプロビジョニングプロファイルと Apple Distribution 証明書を自動的にマッチングします。
  • teamID — ご自身の Apple Developer Team ID。

このファイルを一度作成しておけば、すべての MAS リリースで再利用します。直接配布用の ExportOptions.plist はそのまま残し、このファイルは並べて置きます。

ステップ 2 — App Store Connect へのアプリレコード登録

アプリを実際に審査に提出するには、App Store Connect にアプリのレコード (record) が必要です。レコードは、アプリ名・説明・スクリーンショット・価格など、ストアに表示されるすべての情報を格納する器です。

レコードの作成は実際の初回提出の直前に行っても構いません。 事前設定の段階では、「どの項目をどのように決めればよいか」を事前に把握しておくだけで十分です。特に以下の Primary Language は一度設定すると元に戻しにくいため、あらかじめ慎重に決めておいてください。

App Store Connect → My Apps+New App で次の項目を入力します。

  • PlatformmacOS を選択
  • Primary Language (基本言語) — ⚠️ 最も慎重に決めるべき項目。 一度設定するとセルフサービスで変更することが非常に難しくなります。複数の国にアプリをリリースする予定がある場合、「特定の国の翻訳がない場合に表示される基準言語」となるため、英語 (English, U.S.) を基本言語に設定するケースが多くあります。
  • App Name (アプリ名) — 基本言語での名前 (例: FocusTimer)。他の言語用の名前は、後で言語別のローカライズとして別途追加します。例えば、韓国語ユーザーには韓国語の名前、日本語ユーザーには日本語の名前が表示されるようにできます。
  • Bundle ID — ドロップダウンから com.example.FocusTimer.mas を選択します。1 編で登録したその ID です。直接配布用の Bundle ID (com.example.FocusTimer) と混同しないでください — 必ず .mas が付いている方を選択してください。
  • SKU — 自分だけが使う内部識別用の文字列です。ストアには表示されないため、自由に設定して構いません (例: focustimer-mas-001)。

アプリカテゴリーは、2 編Info.plistLSApplicationCategoryType に設定した値と一致させなければなりません。plist に public.app-category.productivity (生産性) を設定したなら、App Store Connect でもカテゴリーを「生産性」に選ぶ必要があります。そうしないと審査の段階で不一致の警告が表示されます。

ステップ 3 — 両チャネルのビルド検証

1 つのコードベースが 2 つのビルドターゲットを持つようになりました。これにはメンテナンスコストが伴います。普段は直接配布チャネルだけをビルドしていると、MAS ターゲットがいつの間にか壊れていても気づかないことがあります。新しいコードを追加したが #if canImport(Sparkle) の分岐を忘れて、MAS ビルドだけがコンパイルに失敗するようなケースです。

これを防ぐ最も確実な方法は、直接配布のリリースを作るたびに MAS ターゲットも一緒にアーカイブすることです。ビルドが成功すれば、2 つのチャネルの分岐が正常であることを意味します。

xcodebuild -project FocusTimer.xcodeproj -scheme "FocusTimer MAS" \
  -configuration Release \
  -destination 'platform=macOS' \
  -archivePath build/FocusTimer-MAS.xcarchive \
  archive

出力の末尾に次が表示されれば、MAS の分岐は正常です。

** ARCHIVE SUCCEEDED **

このコマンドはリリース自動化スクリプトの最後のステップに組み込み、毎リリースで自動的に実行するようにすることをお勧めします。MAS ビルドを実際に App Store にアップロードするタイミングでなくても、アーカイブが成功するかどうか確認するだけで、2 つのチャネルの分岐が壊れていないことを保証できます。

シリーズまとめ — MAS リリースの事前設定の完了

3 編にわたる Mac App Store リリースの事前設定がすべて完了しました。これで次のものが揃っています。

  • (1 編) MAS 専用の Bundle ID + 複製した FocusTimer MAS ビルドターゲット
  • (2 編) MAS 専用の entitlements・Info.plist + ビルド設定 + #if canImport(Sparkle) コード分岐
  • (3 編) アップロード用 ExportOptions-MAS.plist + App Store Connect レコードの登録方法 + 両チャネルのビルド検証

これにより、1 つの macOS アプリが直接配布 (Developer ID) と Mac App Store の両チャネルを持つようになりました。核心的な構造を改めて整理すると次のとおりです。

  • 同じコードベースを共有しながら、2 つのビルドターゲットに分ける。
  • 直接配布ターゲットは Sparkle を含み、MAS ターゲットは Sparkle を除外する。
  • 2 つの違いは、別々の entitlements・Info.plist・ExportOptions#if canImport(Sparkle) コード分岐で表現される。

初回設定は手間がかかりますが、これも一度整えておけば継続して再利用される構造です。以降は、直接配布のリリースを行う際に MAS ビルドも一緒にアーカイブして分岐が生きているかどうかを確認するだけです。実際の App Store 提出 (スクリーンショット・説明文・審査対応) はこの事前設定の上で行う別の作業であり、他の記事で扱うテーマです。

参考資料