將建置傳送到 App Store 的路徑
第 1 篇建立了 MAS 建置目標,第 2 篇建立了區分兩個渠道的設定檔和程式碼分支。FocusTimer MAS 目標現在已成為可以上架 App Store 的形態。
本篇(最終篇)將搭建將該建置上傳到 App Store Connect 的路徑,並介紹如何驗證兩個渠道在未來不會被破壞,從而收尾本系列。
與第 1、2 篇相同,
FocusTimer、com.example.FocusTimer.mas、Team IDABCDE12345等均為範例值。
第 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=upload—xcodebuild -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)。記錄是容納應用程式在 App Store 中展示的所有資訊的容器,包括應用程式名稱、描述、截圖、價格等。
應用程式記錄可以在實際首次提交前再建立。在一次性準備階段,只需提前了解「需要確定哪些項目、如何確定」即可。特別是下面的 Primary Language,一旦設定便難以更改,請提前慎重決定。
在 App Store Connect → My Apps → + → New App 中填寫以下內容:
- Platform — 選擇 macOS
- Primary Language(主要語言) — ⚠️ 最需要慎重決定的項目。 一旦設定,透過自助服務更改非常困難。若計劃在多個國家發布,通常將**英語(英語,美國)**設為主要語言,因為主要語言是「特定國家沒有對應翻譯時顯示的基準語言」。
- App Name(應用程式名稱) — 以主要語言為基準的名稱(如
FocusTimer)。其他語言的名稱稍後透過各語言在地化 (localization) 單獨新增。例如,可以讓韓語使用者看到韓語名稱,日語使用者看到日語名稱。 - Bundle ID — 從下拉選單中選擇
com.example.FocusTimer.mas。這正是第 1 篇中註冊的那個 ID。請不要與直接分發用 Bundle ID(com.example.FocusTimer)混淆——必須選擇帶有.mas後綴的那個。 - SKU — 僅供你自己使用的內部識別字串,不會在 App Store 中公開,可自由設定(如
focustimer-mas-001)。
應用程式分類必須與第 2 篇中在
Info.plist的LSApplicationCategoryType中填寫的值一致。若在 plist 中填寫了public.app-category.productivity(效率工具),則在 App Store Connect 中也必須選擇「效率工具」類,否則審核階段會出現不符警告。
第 3 步 — 驗證兩個渠道的建置
現在同一程式碼庫擁有了兩個建置目標。這伴隨著維護成本。平時只建置直接分發渠道,MAS 目標可能在不知不覺間已經損壞。例如,新增程式碼時遺漏了 #if canImport(Sparkle) 分支,導致只有 MAS 建置編譯失敗。
防止這種情況最可靠的方法是每次製作直接分發發布時,同時也對 MAS 目標進行封存。若建置成功,則說明兩個渠道的分支完好無損。
xcodebuild -project FocusTimer.xcodeproj -scheme "FocusTimer MAS" \
-configuration Release \
-destination 'platform=macOS' \
-archivePath build/FocusTimer-MAS.xcarchive \
archive
若輸出末尾顯示如下內容,則 MAS 分支正常:
** ARCHIVE SUCCEEDED **
建議將此指令嵌入發布自動化腳本的最後一步,使其在每次發布時自動執行。即使當時並未實際將 MAS 建置上傳到 App Store,僅確認封存是否成功就足以保證兩個渠道的分支沒有被破壞。
系列小結 — MAS 發布一次性準備完成
歷經三篇的 Mac App Store 發布一次性準備工作全部完成。現在你已經準備好以下內容:
- ✅ (第 1 篇) MAS 專用 Bundle ID + 複製的
FocusTimer MAS建置目標 - ✅ (第 2 篇) MAS 專用 entitlements 和 Info.plist + 建置設定 +
#if canImport(Sparkle)程式碼分支 - ✅ (第 3 篇) 用於上傳的
ExportOptions-MAS.plist+ App Store Connect 記錄註冊方法 + 兩個渠道建置驗證
至此,同一個 macOS 應用程式同時具備了直接分發(Developer ID)和 Mac App Store 兩個渠道。核心結構再次總結如下:
- 共享同一程式碼庫,但分為兩個建置目標。
- 直接分發目標包含 Sparkle,MAS 目標排除 Sparkle。
- 兩者的差異透過獨立的 entitlements、Info.plist、ExportOptions 檔案和
#if canImport(Sparkle)程式碼分支來體現。
初次設定時工作量較大,但這同樣是一次建置、持續重複使用的結構。之後只需在製作直接分發發布時同時封存 MAS 建置,確認分支是否仍然正常即可。實際提交 App Store(截圖、描述、應對審核)是在此一次性準備之上進行的獨立工作,將在另一篇文章中介紹。