# iOS 開發者憑證與佈建描述檔：Expo 完整說明

> 憑證證明是誰簽署你的 App，佈建描述檔則指定是哪個 App、能在哪些 iPhone 上執行。用 Expo 的話，EAS 會幫你建立並更新這兩者。

原始頁面：[iOS 開發者憑證與佈建描述檔：Expo 完整說明](https://devoria.fr/zh-hant/blog/ios-developer-certificate-provisioning-profile-expo)
作者：[Mehdi Azizi](https://devoria.fr/zh-hant/mehdi-azizi)
發布日期：2026-11-04
內容最後修訂：2026-11-04


iOS 開發者憑證證明是誰簽署了你的 App。Provisioning profile（佈建描述檔）則把這張憑證綁定到某個特定 App，並說明它可以在哪裡執行。**用 Expo 的話，你幾乎不需要手動製作它們：每次你執行 build，EAS 會自動建立、儲存並更新它們。**

不過，搞懂每個檔案的用途還是很有用。哪天 build 裝不起來，或上傳卡住，就是這些知識能幫你省下一整天。這篇指南會逐一說明四個元素、它們的有效期限、Apple 的限制和常見錯誤，每個錯誤都附上解法。

我用 Expo 和 EAS 發佈我的 iOS App，包括 Solys 和 TradaZen。完整流程請看[沒有 Mac 也能發佈 iOS App](https://devoria.fr/zh-hant/blog/publish-ios-app-without-mac-expo-eas)。這篇則帶你打開簽署機制的引擎蓋。

## 為什麼 Apple 要求簽署

iOS App 必須經過簽署，才能安裝到 iPhone 上或上傳到 App Store Connect。簽署可以保證 App 來自 Apple 認識的開發者，而且之後沒有被任何人修改過。

關於 App Store，有個細節可以讓你放心。根據 [Apple 技術說明 TN3161](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates)，App Store 會在上傳時檢查你的發佈憑證是否有效，接著重新簽署 App，之後 App 就不再受你憑證的到期日影響。**所以你的憑證只需要在上傳當下有效，不需要在 App 整個生命週期都有效。**

## 你需要認識的四個元素

[Expo 關於憑證資料的文件](https://docs.expo.dev/app-signing/app-credentials/)列出 iOS 的三項：發佈憑證、描述檔和推播通知金鑰。我再加上 App ID，沒有它就不會有任何描述檔。

### 發佈憑證

這是你身為開發者的簽名。[Apple 關於憑證的說明](https://developer.apple.com/help/account/certificates/certificates-overview)把憑證分成兩類：

- **Apple Development** 用於開發期間在你的裝置上執行 App。它屬於個人。
- **Apple Distribution** 用於發佈到指定的測試裝置，或上傳到 App Store Connect。它屬於團隊，只有帳號持有人或管理員能建立。

發佈憑證不屬於任何特定 App：同一張憑證可以簽署你所有的 App。它搭配一把私密金鑰，真正負責簽署的就是這把金鑰。根據 TN3161，Apple 憑證一般自建立起有效一年。

### App ID

App ID 在描述檔中用來識別你的 App。它沿用你的 bundle identifier，例如 `com.example.myapp`（虛構範例）。根據 [Apple 說明](https://developer.apple.com/help/account/identifiers/register-an-app-id)，它也帶有允許的功能清單：推播通知、App Groups、Sign in with Apple 等等。

在 Expo 裡，這就是設定中的 `ios.bundleIdentifier` 欄位。**一次選定，不要再改**：它在你的設定和 App Store Connect 裡都必須完全一致。App ID 不會過期。另外根據 [Expo 關於 iOS 功能的文件](https://docs.expo.dev/build-reference/ios-capabilities/)，EAS 每次 build 都會把它的功能和你的設定同步。

### 佈建描述檔

描述檔負責串起一切。它包含一個 App ID、一張憑證，以及依類型而定的授權裝置清單。你會用到三種：

- **開發（Development）**：在你已註冊的裝置上執行測試版 App。
- **Ad hoc**：可安裝在一份指定裝置清單上的 build，每台裝置都以 UDID 識別。這就是 EAS 的「內部發佈」。
- **App Store**：用於 App Store Connect 和 TestFlight。[TN3125 說明](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles)指出，它不包含任何裝置清單。

每個描述檔都有到期日：Apple 說一般不超過一年，Expo 說是 12 個月。

### 推播通知金鑰（APNs）

APNs 金鑰授權你的伺服器（或 Expo 的伺服器）傳送通知給你的 App。它是一個只能下載一次的 .p8 檔：[Apple 不會在你的帳號中保留它](https://developer.apple.com/help/account/keys/create-a-private-key)。同一把金鑰可用於你所有的 App，而且[永遠不會過期](https://developer.apple.com/support/expiration/)。

## 總整理表

| 元素             | 用途              | 有效期限     | 用 Expo 時由誰管理 |
| ---------------- | ----------------- | ------------ | ------------------ |
| 發佈憑證         | 簽署你的 build    | 一般為一年   | EAS（登入後）      |
| App ID           | 識別你的 App      | 不會過期     | 你，再交給 EAS     |
| App Store 描述檔 | 上傳給 Apple      | 最長 12 個月 | EAS                |
| Ad hoc 描述檔    | 安裝到你的 iPhone | 最長 12 個月 | EAS 和你的裝置     |
| APNs 推播金鑰    | 傳送通知          | 不會過期     | EAS 或你           |
| 免費帳號描述檔   | 透過 Xcode 測試   | 7 天         | Xcode，不是 EAS    |

「你，再交給 EAS」：你選定 bundle identifier，EAS 處理功能設定。「EAS 和你的裝置」：你註冊每台測試用 iPhone，EAS 製作描述檔。最後一列是免費 Apple 帳號：根據 [Apple 關於帳號的說明](https://developer.apple.com/help/account/basics/about-your-developer-account)，它的描述檔在建立 7 天後到期。

## 你該知道的 Apple 限制

- **發佈憑證**：每個帳號非常少。Apple 說明寫的是每個團隊每種發佈類型一張，Expo 的表格則寫上限 2 張。記住這條原則：**不要每次 build 或每換一台電腦就建立新憑證。**
- **APNs 金鑰**：根據 Expo，每個帳號最多 2 把。
- **描述檔**：根據 Expo，沒有上限。
- **裝置**：根據 [Apple 關於裝置的說明](https://developer.apple.com/help/account/devices/devices-overview)，每個產品系列每個會籍年度最多 100 台。停用裝置並不會釋出名額。如果你移除了裝置，計數會在下一個會籍年度開始時重置為 100。

## EAS 幫你做的事

根據 [Expo 關於受管憑證的頁面](https://docs.expo.dev/app-signing/managed-credentials/)，你第一次執行 iOS build 時，它會提議產生缺少的項目。你登入 Apple Developer 帳號後，EAS 會建立發佈憑證、描述檔和推播金鑰，並儲存在它的伺服器上。之後的 build 會重複使用它們。

三個實用重點：

- **你的 Apple 密碼留在你的電腦上。** [Expo 的安全性頁面](https://docs.expo.dev/app-signing/security/)說明密碼不會傳送到它的伺服器，而且儲存的憑證資料都經過加密。
- **`eas credentials` 能讓你看到全部**：憑證、描述檔、推播金鑰。這個指令也能替換或移除它們。
- **在 EAS 刪除，不等於在 Apple 那邊刪除。** 要釋出名額，必須到 Apple 入口網站撤銷。

你也可以用本機憑證資料自己掌控：`credentials.json` 檔案指向你的憑證（.p12）和描述檔（.mobileprovision）。Expo 要求把這些檔案加進 `.gitignore`。這和 [Expo App 的 API 金鑰](https://devoria.fr/zh-hant/blog/expo-api-key-security-supabase)是同一條規則：機密永遠不要放進儲存庫。

## 常見錯誤與解法

### 描述檔過期

Ad hoc build 內含它的描述檔：描述檔一到期，App 就無法在你的測試 iPhone 上開啟。不過在 App Store 上，Expo 確認到期對已上架的 App 沒有任何影響。**解法：重新跑一次 build。** EAS 會產生新的描述檔，或者你用 `eas credentials` 自己處理。接著把新 build 重新安裝到你的裝置上。

別和 TestFlight 搞混：TestFlight build 在 90 天後到期，跟你的憑證無關。詳細內容請看[用 TestFlight 測試你的 iPhone App](https://devoria.fr/zh-hant/blog/testflight-test-iphone-app-before-review)。

### 憑證過期或被撤銷

Apple 說得很清楚：只要你的會籍有效，已經在 App Store 上的 App 都不受影響。但你無法再上傳用這張憑證簽署的 build。已上傳但尚未送審的 build，如果憑證被撤銷，可能會被標記為 Invalid Binary。而且[含有已撤銷憑證的描述檔會失效](https://developer.apple.com/help/account/certificates/revoke-a-certificate)。

**解法：透過 `eas credentials` 或在下次 build 時建立新憑證**，再讓 EAS 重新產生描述檔。另外，千萬不要反射性地撤銷一張還能用的憑證。

### 裝置不在 ad hoc 描述檔裡

安裝連結在你這邊可以用，但在某位測試者的 iPhone 上不行。原因：[Expo 關於內部發佈的文件](https://docs.expo.dev/build/internal-distribution/)說明，只有在 build 當下已列在描述檔中的裝置才能安裝 App。

解法：

1. 用 `eas device:create` 註冊裝置。
2. 以互動模式重新 build，並登入你的 Apple 帳號，讓 EAS 更新描述檔。或者用 `eas build:resign` 重新簽署現有的 build，不必整個重新編譯。
3. 在持續整合（CI）環境中，非互動模式會重複使用描述檔，但不會更新它的清單。請加上 `--refresh-ad-hoc-provisioning-profile` 選項。

在新帳號或剛續約的帳號上，Apple 處理新裝置可能要 24 到 72 小時。所以第一個包含它的 build 可能會失敗：等一下再重新執行。

### 達到憑證上限

Apple 拒絕建立新的發佈憑證。通常是有舊憑證還留著：從另一台 Mac 上的 Xcode 建立的，或由其他 build 服務建立的。**如果你有現有憑證的 .p12 檔，就重複使用它。否則，到 Apple 入口網站撤銷不再使用的那張。** 撤銷不會影響已上架的 App，但會讓含有它的描述檔失效。

### 「Provisioning profile doesn't include signing certificate」

Xcode 這則訊息的意思是：描述檔裡沒有私密金鑰在你電腦上的那張憑證。典型原因：混用 Xcode 的自動簽署和 EAS 的憑證資料。**只選一個可信來源**：用受管憑證的 EAS build，或用本機憑證資料，不要兩者並用。

### 撤銷金鑰後通知中斷

如果你撤銷了 APNs 金鑰，Expo 提醒所有使用這把金鑰的 App 都會收不到通知。建立一把新金鑰，再用 `eas credentials` 上傳。你使用者的 Expo Push 權杖不會改變。

### 新增功能後描述檔失效

啟用推播通知或 App Groups 這類服務，[會讓描述檔失效](https://developer.apple.com/help/account/provisioning-profiles/edit-download-or-delete-profiles)：必須重新產生。用 EAS 的話，每次 build 都會同步功能設定。如果描述檔仍被拒絕，可以用 `eas credentials` 產生一個新的。

## 簽署之後的下一步

簽好的 build 只是其中一步。商店頁面、截圖、隱私權和送審都整理在[在 App Store 上架 App](https://devoria.fr/zh-hant/expertise/publish-app-on-app-store)。如果你還沒加入會籍，先從 [Apple 開發者帳號](https://devoria.fr/zh-hant/blog/apple-developer-account-price-free-or-99)開始。想了解我為什麼推薦新手用 Expo，請看[用 React Native 和 Expo 開發行動 App](https://devoria.fr/zh-hant/expertise/react-native-expo-mobile-app)。

## 如果你正在準備第一次上架

第一次上傳前，先做[免費診斷](https://devoria.fr/zh-hant/diagnostic)：它會告訴你專案中真正卡住的地方，並寄給你我的 Apple 防退件檢查清單。

想打造 App、串接訂閱並順利上架，不用跟簽署纏鬥，[iOS & Android Kit](https://devoria.fr/zh-hant/kits/ios) 帶你走完四個步驟，附上我 App 的起始程式碼，按你自己的步調進行。

## 常見問題

### 什麼是 provisioning profile？

它是授權你的 App 執行或上傳到 Apple 的檔案。它串起一個 App ID、一張憑證，以及依類型而定的裝置清單。App Store 描述檔不含任何裝置，ad hoc 描述檔則列出幾台裝置。

### iOS 開發者憑證是免費的嗎？

它沒有另外收費：發佈憑證包含在 Apple Developer Program 中，每年 99 美元。用免費 Apple 帳號的話，Xcode 讓你最多在 3 台裝置上測試，但描述檔 7 天後就會到期，而且無法上架。

### Apple 發佈憑證的有效期限是多久？

根據 Apple，一般自建立起一年。佈建描述檔最長也是 12 個月。至於推播通知金鑰，則永遠不會過期。

### 如果我的發佈憑證過期會怎樣？

只要你的會籍有效，已在 App Store 上的 App 都不受影響。你只是無法再上傳用這張憑證簽署的新 build。用 EAS 的話，下次 build 或執行 `eas credentials` 時就能建立新憑證。

### 建立 iOS 憑證一定要有 Mac 嗎？

如果你用 EAS，就不需要。你從命令列登入 Apple 帳號，EAS 就會產生憑證和描述檔，Windows 和 Linux 都可以。不用 EAS 的話，傳統做法要透過 Mac 上的 Xcode 或鑰匙圈存取。

### Ad hoc 描述檔最多能包含幾台裝置？

你的帳號每個會籍年度最多可註冊 100 台 iPhone，其他每個裝置系列也各有相同數量。停用的裝置仍然算在內。想找更多人測試，請改用 TestFlight。


## 你的專案

[Review Kit](https://devoria.fr/zh-hant/kits/app-review)：我的 App Store 審查檢查清單、我被 Apple 退件後的修正、Google Play 檢查清單，以及三個 Claude Code skill。$1,749。

[iOS & Android Kit](https://devoria.fr/zh-hant/kits/ios)：用 Claude Code 打造你的 iPhone 和 Android App：我自己 App 的起始程式碼、上架商店的完整流程，以及所有套件。$3,599。

[診斷：你離自己的 iPhone App 還差什麼](https://devoria.fr/zh-hant/diagnostic)：7 個問題，60 秒：找出真正卡住你發布 iPhone App 的原因，拿到你的 4 步驟路線，以及最適合你的套件。
