# Guideline 2.5.1：Expo 应用的公开 API 与 SDK 要求

> Guideline 2.5.1 要求只用公开 API、兼容当前 iOS、按用途使用框架。用 Expo 开发，先检查你的原生模块。

原始页面：[Guideline 2.5.1：Expo 应用的公开 API 与 SDK 要求](https://devoria.fr/zh-hans/blog/guideline-2-5-1-public-api-sdk-expo)
作者：[Mehdi Azizi](https://devoria.fr/zh-hans/mehdi-azizi)
发布：2026-11-04
内容最后修订：2026-11-04


Guideline 2.5.1 提出四项要求：只使用公开 API，能在当前 iOS 版本上运行，淘汰 Apple 弃用的东西，按预期用途使用每个框架。**用 Expo 开发时，风险很少来自你的 JavaScript 代码，而是来自你安装的原生模块和你编译所用的 SDK。**

我用 Expo SDK 57 发布了 Solys、TradaZen 和 Nolera。Solys 依赖 Apple 的 Screen Time API，这是一个用途受限的框架。本文讲的是审核规则。如果你是在上传构建时收到报错，请看 [ITMS-90338](https://devoria.fr/zh-hans/blog/itms-90338-non-public-api-usage-expo) 这篇指南。同一部分里相邻的后台模式规则，请看 [guideline 2.5.4](https://devoria.fr/zh-hans/blog/guideline-2-5-4-background-mode-rejection) 那篇。

## Guideline 2.5.1 说了什么？

这条规则位于 [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.1) 的 2.5 部分「Software Requirements」：“Apps may only use public APIs and must run on the currently shipping OS. Keep your apps up-to-date and make sure you phase out any deprecated features, frameworks or technologies that will no longer be supported in future versions of an OS. Apps should use APIs and frameworks for their intended purposes and indicate that integration in their app description.”

简单说，四项义务：

1. **只用公开 API**，也就是 Apple 有文档说明的 API。
2. **应用能在当前 iOS 版本上运行**，2026 年 9 月起是 iOS 27。
3. **不保留即将消失的弃用内容**：Apple 宣布寿命终结的东西，你要替换掉。
4. **每个框架用在该用的地方，并在描述中说明**：HomeKit 用于智能家居，HealthKit 用于健康和运动，并与“健康”App 关联。

所以拒审标题是：“Guideline 2.5.1 - Performance - Software Requirements”。

## 公开 API：Expo 应用里的风险藏在哪里

私有 API 是 Apple 没有公开文档的系统函数。Apple 既不保证它的行为，也不保证它在下一个 iOS 版本中还存在，所以禁止使用。

你的 JavaScript 代码从不直接调用 iOS，而是通过原生模块。Expo SDK 里的模块由 Expo 团队维护。**其他模块里装着不是你写的代码，但 Apple 会像审查你的代码一样审查它。** [ITMS-90683](https://devoria.fr/zh-hans/blog/itms-90683-missing-purpose-string-expo) 这篇指南展示了权限说明文字的同一机制：Apple 看的是构建中存在的代码，而不是应用实际做了什么。

截至 2026 年 10 月 15 日，Solys 有 42 个直接依赖包含原生 iOS 代码，其中 14 个不在 Expo SDK 里。包括 RevenueCat、Sentry、AppsFlyer，以及连接 Screen Time API 的 `react-native-device-activity`。

私有 API 可能在两个时间点被发现。上传时，App Store Connect 的自动分析可能返回 ITMS-90338 错误。审核时，审核员会引用 2.5.1。

## 弃用的 API：从 UIWebView 到 UIScene

最有名的例子是 UIWebView，一个用来显示网页的旧组件。Apple 在 2020 年 4 月[停止接受](https://developer.apple.com/news/?id=12232019b)新应用使用它，2020 年 12 月起更新也不再接受。一个仍引用它的老库就会卡住上传。在 Solys 上，下面检查清单里的搜索找不到任何引用。

下一次变化已经宣布。Apple 的技术说明 [TN3187](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle) 写道：“In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won't launch.” 意思是：用 iOS 27 SDK 编译、却没有基于场景生命周期的应用，将无法启动。

需要把三个日期联系起来看：

- **自 2026 年 4 月起**，Apple 要求 Xcode 26：这是 [ITMS-90725](https://devoria.fr/zh-hans/blog/itms-90725-sdk-version-issue-expo) 指南的主题。
- **2027 年 4 月**，[Apple 的提交页面](https://developer.apple.com/app-store/submitting/)宣布 iOS 27 SDK 将成为强制要求。
- **Expo SDK 58** 自 2026 年 9 月 15 日起进入测试版，根据 [Expo 的公告](https://expo.dev/changelog/sdk-58-beta)，它已经会生成场景管理代码。

用 Expo SDK 57 和 Xcode 26，你仍然是用 iOS 26 SDK 编译：现在什么都不会坏。**修改 AppDelegate 的模块必须在 2027 年 4 月前跟上。**

## 框架被用在预期用途之外

审核员会检查敏感框架是否服务于一个可见的功能，以及你的商品页面是否提到了它。

- **HealthKit** 用于健康和运动。[Apple 的界面设计指南](https://developer.apple.com/design/human-interface-guidelines/healthkit)写道：“If your app doesn't provide health and fitness functionality, don't request access to people's private health data.”
- **HomeKit** 用于智能家居，别无他用。
- **PushKit** 用于网络语音通话（VoIP）。[PushKit 文档](https://developer.apple.com/documentation/pushkit/responding-to-voip-notifications-from-pushkit)说得很明确：“If you are unable to support CallKit in your app, you cannot use PushKit to handle push notifications.” 没有来电却用 VoIP 通知唤醒应用，就是滥用。
- **Family Controls**，即 Screen Time API，需要特殊授权。它的[文档](https://developer.apple.com/documentation/familycontrols)说明：“Before submitting your app to the App Store, you must request permission to use the entitlement.”

对于 Solys，我在 2026 年 9 月 23 日申请了这项分发授权，Apple 当天就批准了。用途和框架完全吻合：用户选择要暂停的应用，Solys 在起床后 30、45 或 60 分钟内屏蔽它们。商品页面的描述用一句话说明了这一点：“Solys 使用 Apple 的 Screen Time 授权来暂停所选应用。”**这正是 2.5.1 结尾的要求：在描述中说明这项集成。**

## 测试版：TestFlight 可以，App Store 不行

[App Store Connect 的版本说明](https://developer.apple.com/help/app-store-connect/release-notes/)展示了这条规则的实际执行。2026 年 10 月 14 日，用 Xcode 27.2 beta 3 构建的版本被接受“for internal and external testing”，也就是用于 TestFlight。10 月 5 日，Xcode 27.1 RC 的构建被接受“for the App Store”。

**用 Xcode 测试版编译的构建可以进 TestFlight，但永远不能提交审核。** 要提交，你需要正式版，或者 Apple 已对 App Store 开放的 RC 版。

对 Expo 应用补充两点：

- **Expo 的测试版不等于 Apple 的测试版。** Apple 检查的是 Xcode 和 iOS SDK 的版本，而不是 Expo 的版本。SDK 58 的公告还提到，带 Xcode 27 的 EAS 镜像即将推出。
- **在当前 iOS 上测试仍然是必须的**，即使你用 iOS 26 SDK 编译。在已更新的 iPhone 或模拟器上冷启动应用。

## 检查清单：提交前检查原生依赖

每次生产构建前过一遍。命令在 Expo 项目根目录运行：

```bash
npx expo-doctor
npx expo install --check
grep -rlw "UIWebView" node_modules --include='*.m' --include='*.mm' --include='*.swift' --include='*.h'
```

1. **`npx expo-doctor` 没有报告任何失败。** 在 Solys 上，2026 年 10 月 15 日：21 项检查通过 20 项。失败原因是 13 个 Expo 包落后一个补丁版本，`npx expo install --check` 可以把它们对齐。
2. **每个 Expo SDK 之外的模块都收录在 React Native Directory 中。** 按照 [Expo 文档](https://docs.expo.dev/versions/latest/config/package-json/)，Expo Doctor 默认会做这项检查。不认识的包，值得读一读它的 iOS 代码。
3. **每个原生模块都跟得上你的 React Native 版本。** [Expo 版本对照表](https://docs.expo.dev/versions/latest/)将 SDK 57 对应到 React Native 0.86。一个好几个版本都没发布过的模块，是个警示信号。
4. **UIWebView 搜索没有任何结果。** 对 Apple 宣布寿命终结的任何 API 都照此处理。
5. **每个敏感框架都有可见的功能**：健康、Screen Time、通话、家居。描述中有提及，特殊授权也已获批。
6. **构建来自 Xcode 正式版。** 在 EAS 构建日志里检查版本。
7. **应用能在当前 iOS 版本上冷启动**，使用全新账号。
8. **涉及 AppDelegate 的模块已声明支持 UIScene**，在你升级到 iOS 27 SDK 之前。

## 如何回复 2.5.1 拒审？

消息通常会点名涉及的 API 或框架。分两种情况：

- **框架没有任何可见用途**：移除该模块或能力，重新构建，然后用两句话回复。
- **框架服务于真实功能**：给出确切的操作路径、一张截图或一段短视频，并在商品页面描述中说明这项集成。

**移除原生模块会改变二进制文件：远程更新不够。** [guideline 2.1](https://devoria.fr/zh-hans/blog/app-store-guideline-2-1-rejection-fix) 指南解释了为什么审核员只看得到打包进去的代码。之后的沟通在 App Store Connect 中进行，参见[回复 App Review](https://devoria.fr/zh-hans/blog/apple-resolution-center-reply-app-review-rejection) 指南。

## 提交前检查你的项目

[Review Kit](https://devoria.fr/zh-hans/kits/app-review) 汇集了我的提交前检查清单、我修复过的拒审案例，以及能审阅你 Expo 项目的 Claude Code skills。想要人工把关，[和我预约一小时](https://devoria.fr/zh-hans/coaching)：我们一起读 Apple 的消息和你的依赖。完整流程见[应用被 Apple 拒审](https://devoria.fr/zh-hans/expertise/app-rejected-by-apple)页面。

在准备第一次上架？[做一下免费诊断](https://devoria.fr/zh-hans/diagnostic)：它会把我的 Apple 防拒审检查清单发给你。

## 常见问题

### “Guideline 2.5.1 - Performance - Software Requirements” 是什么意思？

当 Apple 认为你的应用使用了非公开 API、弃用技术，或把框架用在预期用途之外时，拒审就会用这个标题。消息通常会点名涉及的内容。

### Guideline 2.5.1 和 ITMS-90338 错误有什么区别？

ITMS-90338 是上传构建时收到的自动错误，在分析发现非公开符号时触发。2.5.1 是由人执行的审核规则，还涵盖被滥用的框架和弃用技术。

### 能提交用 Xcode 测试版编译的应用吗？

不能。App Store Connect 只接受这类构建用于 TestFlight。要提交审核，请用 Xcode 正式版编译，或者用 Apple 在版本说明中已对 App Store 开放的 RC 版。

### Expo 应用会在不知情的情况下使用私有 API 吗？

会，通过第三方原生模块。你的 JavaScript 代码本身不调用 iOS，但每个原生包都带有 Objective-C 或 Swift 代码。每次发版前，看一遍 Expo SDK 之外的模块清单。

### 需要马上升级到 Expo SDK 58 吗？

截至 2026 年 10 月 15 日，就 2.5.1 而言不需要：SDK 57 用 iOS 26 SDK 编译，目前仍被接受。请在 2027 年 4 月前安排升级，届时 Apple 将要求 iOS 27 SDK 和基于场景的生命周期。


## 你的项目

[Review Kit](https://devoria.fr/zh-hans/kits/app-review)：我的 App Store 审核清单、我被 Apple 拒审后的修正方案、Google Play 审核清单，以及三个 Claude Code skill。¥369。

[iOS & Android Kit](https://devoria.fr/zh-hans/kits/ios)：用 Claude Code 打造你的 iPhone 和 Android 应用：我自己应用的起步代码、上架商店的完整流程，以及全部工具包。¥739。

[诊断：你离自己的 iPhone 应用还差什么](https://devoria.fr/zh-hans/diagnostic)：7 个问题，60 秒：看清真正阻碍你发布 iPhone 应用的原因，拿到你的 4 步路线和适合你的套件。
