# EAS Submit iOS 上架 App Store 教學

> EAS Submit 把 iOS build 傳到 App Store Connect 並進入 TestFlight，送審仍要手動完成。

原始頁面：[EAS Submit iOS 上架 App Store 教學](https://devoria.fr/zh-hant/blog/eas-submit-ios-expo-app-store)
作者：[Mehdi Azizi](https://devoria.fr/zh-hant/mehdi-azizi)
發布日期：2026-10-25
內容最後修訂：2026-10-25


`eas submit --platform ios` 會把你的 iOS build 傳到 App Store Connect，經過 Apple 處理後，它會出現在 TestFlight。**這個指令不會把你的 app 送交 Apple 審查：選擇 build 和送審，還是要在 App Store Connect 裡完成。**想要自動化，它需要你的 app 頁面編號（`ascAppId`）和一把 App Store Connect API 金鑰。

我的 iOS app，包括 Solys、TradaZen 和 Nolera，都是用 Expo、EAS Build 和 EAS Submit 發布的。這篇指南依據 [Expo 的 iOS 上傳文件](https://docs.expo.dev/submit/ios/)，於 2026 年 10 月 25 日重新核對過。沒有 Mac 的話，完整流程請看[沒有 Mac 也能發布 iOS app](https://devoria.fr/zh-hant/blog/publish-ios-app-without-mac-expo-eas)。這篇只專注在上傳這一步。

## 第一次下指令前要準備什麼

Expo 列出三個前置條件：

- **一個付費的 Apple Developer 帳號。**價格和註冊方式請看 [Apple 開發者帳號](https://devoria.fr/zh-hant/blog/apple-developer-account-price-free-or-99)。
- **`ios.bundleIdentifier` 裡的 bundle identifier。**根據 [Expo 設定檔參考文件](https://docs.expo.dev/versions/latest/config/app/)，它由你自己取，但在 App Store 上必須是唯一的。
- **安裝好 EAS CLI**，再用你的 Expo 帳號執行 `eas login`。

你還需要一個已簽章的 production build。EAS Build 會用它幫你管理的憑證和描述檔來產生，詳見 iOS 憑證與 provisioning profile。

### App Store Connect 的 app 頁面：自己建還是交給 EAS？

EAS Submit 會把二進位檔傳到一個必須已經存在於 App Store Connect 的 app。

**你可以自己建立。**[Apple 的說明](https://developer.apple.com/help/app-store-connect/create-an-app-record/add-a-new-app)描述了 New App 視窗：平台、名稱、主要語言、bundle identifier、SKU 和使用者存取權限。你需要 Account Holder、Admin 或 App Manager 角色。

**EAS 也可以在第一次上傳時幫你建立。**根據 [Expo 的 TestFlight 頁面](https://docs.expo.dev/submit/testflight/)，`eas submit` 會在你上傳第一個 build 時建立 app 頁面。依照 [eas.json 參考文件](https://docs.expo.dev/eas/json/)，填了 `ascAppId` 就會跳過這一步。名稱取自 `appName`，沒有的話就用設定檔裡的 `name`。主要語言取自 `language`，預設是 `en-US`。**如果你的 app 先以法文推出，請在第一次上傳前先填好 `language`。**

接著，把 app 頁面的編號抄到 `ascAppId`。Expo 說明了位置：在 App Store Connect 開啟你的 app，進入 App Information。就是 General Information 底下的 Apple ID 欄位。**它是一個數字，不是你的 bundle identifier。**

## 為什麼用 API 金鑰而不是 Apple ID

EAS Submit 可以用你的 Apple ID 或 App Store Connect API 金鑰連線到 Apple。

Apple ID 會卡在雙重認證，[Apple 要求](https://developer.apple.com/support/authentication/)所有 App Store Connect 使用者都要啟用：必須有人確認登入。透過 `EXPO_APPLE_APP_SPECIFIC_PASSWORD` 傳入的 App 專用密碼可以避開這一步，但 [Expo 認為它不如](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md) API 金鑰安全，API 金鑰才是它預設且推薦的方式。**金鑰可以完全不需互動就完成認證，因此能讓上傳自動化。**

取得金鑰有兩種方式：

- **交給 EAS 管理。**執行 `eas credentials --platform ios`，選擇 `production` profile，登入你的 Apple 帳號，然後選「App Store Connect: Manage your API Key」。
- **用你自己的金鑰。**在 App Store Connect：Users and Access，Integrations 分頁，App Store Connect API，Team Keys，然後 Generate API Key。需要 Admin 帳號，而 [Expo 的指南](https://github.com/expo/fyi/blob/main/creating-asc-api-key.md)會給金鑰 Admin 角色。

第二種情況下，記下顯示在有效金鑰列表中的 Key ID，以及 [Integrations 頁面上方](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests)的 Issuer ID。最重要的是保管好 `.p8` 檔：[你只能下載一次](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api)，Apple 不會保留任何副本。

> 根據 Apple 的說法，Admin 金鑰可以新增和刪除你帳號裡的使用者。Apple 要求絕對不要把金鑰放進程式碼儲存庫。

## 可以直接複製的最小 eas.json

所有值都是假的：換成你自己的。

```json
{
  "cli": {
    "appVersionSource": "remote"
  },
  "build": {
    "production": {
      "autoIncrement": true
    }
  },
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890",
        "appleTeamId": "ABCDE12345",
        "ascApiKeyPath": "./keys/AuthKey_XXXXXXXXXX.p8",
        "ascApiKeyIssuerId": "your-issuer-id",
        "ascApiKeyId": "XXXXXXXXXX"
      }
    }
  }
}
```

- **`appVersionSource` 和 `autoIncrement`**：EAS 伺服器保存 build 號碼，並在每次 production build 時遞增。從 EAS CLI 12 開始，[Expo 推薦這種遠端模式](https://docs.expo.dev/build-reference/app-versions/)。
- **`ascAppId`**：你的 app 頁面編號。沒有它，非互動模式會失敗。
- **`appleTeamId`**：你的 Apple Developer 團隊 ID。
- **`ascApiKeyPath`、`ascApiKeyIssuerId`、`ascApiKeyId`**：你的 API 金鑰。這三個欄位都接受環境變數。記得把 `keys` 資料夾加進 `.gitignore`。

`appleId` 欄位只有在你用 Apple ID 登入時才需要。如果 EAS 已經在管理你的金鑰，也把三個 `ascApiKey` 欄位拿掉。我的三個 app 在 10 月 25 日重新檢查過，production 上傳 profile 裡只有 `ascAppId`，Solys 再多一個 `appleTeamId`：檔案裡沒有任何金鑰。

## 先 build，再上傳

```bash
eas build --platform ios --profile production
eas submit --platform ios
```

不加其他選項時，`eas submit` 會讓你選擇要上傳的 build，第一次執行時還會要你輸入 Apple ID。如果存在 `production` 上傳 profile，就會預設使用它。[EAS CLI 參考文件](https://docs.expo.dev/eas/cli/)列出了可以省去選擇步驟的選項：

| 選項             | 作用                 |
| ---------------- | -------------------- |
| `--latest`       | 上傳最新的 iOS build |
| `--id`           | 上傳指定的 EAS build |
| `--path`         | 上傳本機的 .ipa 檔   |
| `--url`          | 上傳線上的封存檔     |
| `--groups`       | 加入內部測試群組     |
| `--what-to-test` | 填寫「What to test」 |

想一氣呵成，就在 build 指令加上 `--auto-submit`。根據 [Expo 的自動上傳頁面](https://docs.expo.dev/build/automate-submissions/)，build 完成後會用與 build profile 同名的上傳 profile 交給 EAS Submit。想用別的 profile：`--auto-submit-with-profile=name`。**build 會送到 TestFlight，不是送審。**

在 CI 中，加上 `--non-interactive` 和 `EXPO_TOKEN` 權杖。這時指令無法問你任何問題：profile 裡必須有 `ascAppId`，還要有 API 金鑰，可以是 EAS 綁定到這個 app 的金鑰，或是你填在三個 `ascApiKey` 欄位裡的金鑰。

## 上傳之後會發生什麼

**1. Apple 處理 build。**build 必須經過這個處理才會出現在 App Store Connect，處理完成時 [Apple 會寄 email 給你](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds)。Expo 表示通常要 10 到 15 分鐘才會在 TestFlight 看到。

**2. 出口合規。**Missing Compliance 狀態表示缺少你的加密聲明。每個新版本 App Store Connect 都會問這些問題，除非 Info.plist 已經回答了。在 Expo 裡，這個鍵叫 `ios.config.usesNonExemptEncryption`：

```json
{
  "expo": {
    "ios": {
      "config": {
        "usesNonExemptEncryption": false
      }
    }
  }
}
```

根據 [Apple](https://developer.apple.com/documentation/security/complying-with-encryption-export-regulations)，如果你的 app（包含函式庫）完全沒用加密，或只用了豁免的加密，就可以設 `false`。系統內建的加密，例如透過 URLSession 的 HTTPS，通常屬於豁免。**只有在對你的 app 屬實時才宣告 `false`：這份聲明是要負責的。**跟所有 Info.plist 的鍵一樣，改了要重新 build。

**3. TestFlight。**[根據 Apple](https://developer.apple.com/help/app-store-connect/reference/app-build-statuses)，在 Ready to Submit 狀態下，build 可以發給內部測試者、通過外部測試的 beta 審查，或送交 App Store 審查。profile 裡的 `groups` 欄位會把它加入你的內部群組。其他細節都在 [用 TestFlight 測試你的 app](https://devoria.fr/zh-hant/blog/testflight-test-iphone-app-before-review)。

## 上傳不等於送審

[Expo 寫得很清楚](https://docs.expo.dev/submit/introduction/)：TestFlight build 不會自動發布到 App Store。EAS Submit 不會幫你填 app 頁面，也不會上傳截圖。在 App Store Connect 裡還剩四個動作，[Apple 的送審說明](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-an-app)有詳細描述：

1. **填寫該版本的必填中繼資料。**
2. **在版本的 Build 區塊選擇 build。**
3. **點「Add for Review」。**版本會變成 Ready for Review，但還沒有真的送審。
4. **點「Submit for Review」。**審查開始時，狀態會變成 In Review。

## 常見錯誤與修正方式

| 顯示的錯誤          | 原因                 | 修正方式                  |
| ------------------- | -------------------- | ------------------------- |
| ITMS-90189          | build 號碼已被使用   | `autoIncrement`           |
| ITMS-90062 或 90186 | 版本已關閉           | 調高 `version`            |
| 「Set ascAppId」    | CI 中缺少 `ascAppId` | 加上 `ascAppId`           |
| 「API Keys cannot」 | 沒有綁定任何金鑰     | `eas credentials`         |
| ITMS-90683          | 缺少權限用途說明     | `ios.infoPlist`           |
| ITMS-91053          | 隱私清單不完整       | `ios.privacyManifests`    |
| ITMS-90725          | iOS SDK 太舊         | 升級 Expo SDK             |
| Missing Compliance  | 未宣告加密           | `usesNonExemptEncryption` |

根據 Expo，build 號碼重複是上傳被拒的常見原因：詳見 build 號碼與版本號。有三種錯誤有專屬指南：[Expo 的 ITMS-90683](https://devoria.fr/zh-hant/blog/itms-90683-missing-purpose-string-expo)、[Expo 的 ITMS-91053](https://devoria.fr/zh-hant/blog/itms-91053-missing-api-declaration-expo) 和 ITMS-90725。

引號中的兩則訊息來自 EAS，在它的設定裡就能修正。Missing Compliance 也可以直接在 App Store Connect 回答問題解決。**其他所有錯誤，修正都涉及二進位檔：重新 build，再重新上傳。**遠端更新改不了 Info.plist、隱私清單，也改不了版本號碼。

## 不用摸索就送出你的第一個 app

指令只是其中一步。[iOS Kit](https://devoria.fr/zh-hant/kits/ios) 以我 app 的 Starter Code 為基礎，包含訂閱功能，用四個步驟帶你一路走到 App Store，按你自己的步調進行。

如果你正在準備第一次上架，[來做免費診斷](https://devoria.fr/zh-hant/diagnostic)：它會告訴你真正卡住你的是什麼，並寄給你我的 Apple 防退件檢查清單。關於 app 頁面、截圖和審核，[在 App Store 發布 app](https://devoria.fr/zh-hant/expertise/publish-app-on-app-store) 這頁涵蓋了每個步驟。

## 常見問題

### 怎麼把 Expo app 發布到 App Store？

用 EAS Build 跑一個 production build，再用 `eas submit --platform ios` 上傳。Apple 處理完後，它會出現在 TestFlight。接著在 App Store Connect 填好 app 頁面，在版本裡選這個 build，然後點「Add for Review」和「Submit for Review」。

### EAS Submit 會把我的 app 送交 Apple 審查嗎？

不會。EAS Submit 把二進位檔傳到 App Store Connect，build 會進入 TestFlight。送審要在 App Store Connect 手動完成，前提是 app 頁面已填好、build 已選好。

### 我的 app 的 ascAppId 在哪裡找？

在 App Store Connect 開啟你的 app，進入 App Information。就是 General Information 底下的 Apple ID 欄位。它是一個數字，別跟你的 bundle identifier 搞混。

### 使用 eas submit 需要 Apple ID 嗎？

第一次執行時，指令會要你輸入。之後只要 profile 裡有 `ascAppId`，再加上一把 App Store Connect API 金鑰，就能不需互動地執行，連 CI 也可以。API 金鑰是 Expo 預設且推薦的方式。

### 要多久才能在 TestFlight 看到 build？

Expo 表示 Apple 處理通常要 10 到 15 分鐘，完成時 Apple 會寄 email 給你。如果 build 一直停在 Missing Compliance 狀態，先回答加密相關問題，再在設定檔裡宣告，之後的 build 就不用再答。


## 你的專案

[Apple Review Kit](https://devoria.fr/zh-hant/kits/review-apple)：我使用的 App Store 審核檢查清單、我被 Apple 退件後的修正、給審核人員的備註，以及兩個審閱你 App 的 Claude Code skills。29 €。

[iOS Kit](https://devoria.fr/zh-hant/kits/ios)：用 Claude Code 打造你的 iPhone App：我的 App 所用的 Starter Code、檢查成果的 skills，以及 Apple Review Kit、App Store Screenshots Kit 與 ASO Kit。129.99 €。
