iOS 开发者证书与描述文件:Expo 签名指南
作者:Mehdi Azizi
发布于 ,9分钟
证书证明是谁签名了你的 App,描述文件说明是哪个 App、能装在哪些 iPhone 上。用 Expo 的话,EAS 会帮你创建并续期这两者。
iOS 开发者证书用来证明是谁签名了你的 App。描述文件(provisioning profile)则把这张证书和某个具体的 App 绑定起来,并说明它可以在哪里运行。用 Expo 的话,你几乎不用手动制作它们:每次你发起构建,EAS 都会自动创建、保存并续期。
但搞懂每个文件是干什么的,仍然很有用。哪天构建装不上,或者上传卡住了,正是这些知识能帮你省下一整天。这篇指南会逐一讲解四个要素、它们的有效期、Apple 的各种限制,以及常见错误和对应的解决办法。
我用 Expo 和 EAS 发布自己的 iOS App,其中包括 Solys 和 TradaZen。完整流程见没有 Mac 也能发布 iOS App。这篇我们来拆开签名的“引擎盖”看看。
为什么 Apple 要求签名
iOS App 必须签名,才能安装到 iPhone 上,或者上传到 App Store Connect。签名保证 App 来自 Apple 认识的开发者,而且之后没有被任何人改动过。
对 App Store 来说,有个细节可以让你放心。根据 Apple 技术说明 TN3161,App Store 会在你上传时检查分发证书是否有效,然后对 App 重新签名,之后 App 就不再依赖你证书的过期时间。所以你的证书只需要在上传那一刻有效,不需要在 App 的整个生命周期里都有效。
你需要了解的四个要素
Expo 关于凭据的文档列出了 iOS 的三项:分发证书、描述文件和推送通知密钥。我再加上 App ID,没有它,任何描述文件都不存在。
分发证书
这是你作为开发者的签名。Apple 关于证书的帮助文档区分了两类:
- Apple Development 用于开发期间在你自己的设备上运行 App。它属于个人。
- Apple Distribution 用于分发到指定的测试设备,或上传到 App Store Connect。它属于团队,只有账户持有人或管理员才能创建。
分发证书不针对某个特定的 App:同一张证书可以签名你所有的 App。它配有一把私钥,真正用来签名的就是这把私钥。根据 TN3161,Apple 证书一般自创建之日起有效一年。
App ID
App ID 在描述文件里标识你的 App。它就是你的 Bundle ID,比如 com.example.myapp(虚构示例)。根据 Apple 的帮助文档,它还带有允许使用的功能列表:推送通知、App Groups、Sign in with Apple……
在 Expo 里,它对应配置中的 ios.bundleIdentifier 字段。一次定好,别再改:它在任何地方都必须一致,配置里和 App Store Connect 里都一样。App ID 不会过期。而且根据 Expo 关于 iOS 功能的文档,EAS 每次构建都会把它的功能和你的配置同步。
描述文件
描述文件负责把东西连起来。它包含一个 App ID、一张证书,以及(视类型而定)一份允许的设备列表。和你相关的有三种:
- 开发(Development):在你已注册的设备上运行测试版 App。
- Ad hoc:可以安装到一份指定设备列表上的构建,每台设备用 UDID 标识。这就是 EAS 的“内部分发”。
- App Store:用于 App Store Connect 和 TestFlight。技术说明 TN3125 解释说,它不包含任何设备列表。
每个描述文件都有过期时间:Apple 说一般不超过一年,Expo 说是 12 个月。
推送通知密钥(APNs)
APNs 密钥允许你的服务器(或 Expo 的服务器)向你的 App 发送通知。它是一个 .p8 文件,只能下载一次:Apple 不会在你的账户里保留它。同一把密钥可以用于你所有的 App,而且它永远不会过期。
汇总表
| 要素 | 用途 | 有效期 | 用 Expo 时由谁管理 |
|---|---|---|---|
| 分发证书 | 签名你的构建 | 一般一年 | EAS,登录后 |
| App ID | 标识你的 App | 不过期 | 你,然后是 EAS |
| App Store 描述文件 | 上传给 Apple | 最长 12 个月 | EAS |
| Ad hoc 描述文件 | 安装到你的 iPhone | 最长 12 个月 | EAS 和你的设备 |
| APNs 推送密钥 | 发送通知 | 不过期 | EAS 或你 |
| 免费账户描述文件 | 通过 Xcode 测试 | 7 天 | Xcode,不是 EAS |
“你,然后是 EAS”:Bundle ID 由你来定,功能由 EAS 处理。“EAS 和你的设备”:每台测试 iPhone 由你注册,描述文件由 EAS 生成。最后一行说的是免费 Apple 账户:根据 Apple 关于账户的帮助文档,它的描述文件在创建 7 天后过期。
你需要知道的 Apple 限制
- 分发证书:每个账户很少。Apple 帮助文档说每个团队每种分发类型只能有一张,Expo 的表格写的是上限 2 张。记住这条规则:不要每次构建或每换一台电脑就新建一张证书。
- APNs 密钥:根据 Expo,每个账户最多 2 把。
- 描述文件:根据 Expo,没有上限。
- 设备:根据 Apple 关于设备的帮助文档,每个产品系列每个会员年度最多 100 台。停用设备不会腾出名额。如果你移除了设备,计数会在下一个会员年度开始时重置为 100。
EAS 帮你做了什么
根据 Expo 关于托管凭据的页面,你第一次做 iOS 构建时,它会提议生成缺少的东西。你登录 Apple Developer 账户,EAS 就会创建分发证书、描述文件和推送密钥,并保存在它的服务器上。之后的构建会复用它们。
三个有用的点:
- 你的 Apple 密码只留在你的电脑上。 Expo 的安全页面说明,密码不会发送到它的服务器,存储的凭据也是加密的。
eas credentials能让你看到一切:证书、描述文件、推送密钥。这个命令还可以替换或移除它们。- 在 EAS 里删除,不等于在 Apple 那边删除。 想腾出名额,得去 Apple 开发者门户吊销。
你也可以用本地凭据自己掌控:一个 credentials.json 文件指向你的证书(.p12)和描述文件(.mobileprovision)。Expo 要求把这些文件加进 .gitignore。这和 Expo App 的 API 密钥是同一条规则:秘密永远不能进代码仓库。
常见错误及解决办法
描述文件过期
Ad hoc 构建自带描述文件:一旦过期,App 在你的测试 iPhone 上就打不开了。而在 App Store 上,Expo 确认过期对线上 App 没有任何影响。解决办法:重新构建一次。 EAS 会生成新的描述文件,或者你自己用 eas credentials 来做。然后把新构建重新装到你的设备上。
别和 TestFlight 搞混:TestFlight 构建 90 天后过期,跟你的证书无关。详情见用 TestFlight 测试你的 iPhone App。
证书过期或被吊销
Apple 说得很清楚:只要你的会员资格有效,已经上架 App Store 的 App 不受影响。但你不能再上传用这张证书签名的构建。已上传但尚未提交审核的构建,如果证书被吊销,可能会被标记为 Invalid Binary。而且包含已吊销证书的描述文件会失效。
解决办法:通过 eas credentials 或在下次构建时创建一张新证书,然后让 EAS 重新生成描述文件。还有,千万别条件反射地去吊销一张正常工作的证书。
设备不在 Ad hoc 描述文件里
安装链接在你这边能用,在某个测试者的 iPhone 上却不行。原因:Expo 关于内部分发的文档解释,只有构建时已在描述文件中的设备才能安装 App。
解决办法:
- 用
eas device:create注册设备。 - 以交互模式重新构建,并登录你的 Apple 账户,让 EAS 更新描述文件。或者用
eas build:resign给现有构建重新签名,不用全部重新编译。 - 在持续集成中,非交互模式会复用描述文件但不更新设备列表。加上
--refresh-ad-hoc-provisioning-profile选项。
在新账户或刚续费的账户上,Apple 处理一台新设备可能需要 24 到 72 小时。所以包含它的第一次构建可能会失败:等一等,再重新构建。
证书数量达到上限
Apple 拒绝创建新的分发证书。通常是有旧证书还留着:在另一台 Mac 上用 Xcode 创建的,或者由别的构建服务创建的。如果你有现有证书的 .p12 文件,就复用它。否则,去 Apple 开发者门户吊销不再使用的那张。 吊销不会影响你已经上线的 App,但会让包含它的描述文件失效。
“Provisioning profile doesn't include signing certificate”
Xcode 的这条消息意思是:描述文件里没有那张私钥在你电脑上的证书。典型原因:混用了 Xcode 的自动签名和 EAS 的凭据。只选一个唯一的来源:要么用托管凭据的 EAS 构建,要么用本地凭据,不要两者混用。
吊销密钥后通知中断
如果你吊销了 APNs 密钥,Expo 提醒说,所有使用它的 App 都会收不到通知。创建一把新密钥,用 eas credentials 上传。你用户的 Expo Push 令牌不会改变。
新增功能后描述文件失效
启用推送通知或 App Groups 这类服务,会让描述文件失效:必须重新生成。用 EAS 的话,每次构建都会同步功能。如果描述文件仍然被拒,可以用 eas credentials 生成一个新的。
签名之后的下一步
签好名的构建只是其中一步。商店页面、截图、隐私信息和提交审核,都整理在在 App Store 上发布应用里。如果你还没加入开发者计划,先看Apple 开发者账户。想知道我为什么推荐新手用 Expo,读读用 React Native 和 Expo 做移动 App。
如果你正在准备第一次发布
第一次上传前,先做一下免费诊断:它会告诉你项目里真正卡住的是什么,并把我的防 Apple 拒审清单发给你。
想把 App 做出来、接入订阅、顺利发布而不用跟签名死磕,iOS & Android Kit 按四个步骤带你走完全程,附带我自己 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 不受任何影响。你只是不能再上传用这张证书签名的新构建。用 EAS 的话,下次构建时或用 eas credentials 就能创建一张新证书。
创建 iOS 证书需要 Mac 吗?
如果用 EAS,就不需要。你在命令行里登录 Apple 账户,EAS 就会生成证书和描述文件,Windows 和 Linux 上都可以。不用 EAS 的话,传统方法要通过 Mac 上的 Xcode 或钥匙串访问。
一个 Ad hoc 描述文件能包含多少台设备?
你的账户每个会员年度最多可以注册 100 台 iPhone,其他每个设备系列也各有同样的额度。停用的设备仍然计数。想让更多人测试,就用 TestFlight。

