# ITMS-90683 错误：Expo 修复方法

> ITMS-90683 表示 Info.plist 缺少用途说明。在 app.json 的 ios.infoPlist 中补上邮件提到的键，再重新构建即可。

原始页面：[ITMS-90683 错误：Expo 修复方法](https://devoria.fr/zh-hans/blog/itms-90683-missing-purpose-string-expo)
作者：[Mehdi Azizi](https://devoria.fr/zh-hans/mehdi-azizi)
发布：2026-10-09
内容最后修订：2026-10-09


ITMS-90683 是 Apple 的自动拒绝：它会在你上传构建后不久通过邮件发来，早于任何人工审核。意思是你的 Info.plist 文件里缺了一句话，用来解释 app 为什么要访问某项敏感数据。**修复只需两步：把邮件里提到的键加到 `ios.infoPlist`，然后重新构建。**

我在 Solys（我的小游戏闹钟）上就碰到过，而且涉及的数据 app 根本没用到。下面说说这条消息是什么意思、为什么会触发，以及怎么避免。

## ITMS-90683 错误是什么意思？

完整消息标题是“ITMS-90683: Missing purpose string in Info.plist”。它表示你 app 的代码引用了某个涉及敏感数据的 API（照片、相机、麦克风、位置、通讯录），而 Info.plist 里没有对应的说明键。消息会写出这个键的名字，比如 `NSPhotoLibraryUsageDescription`。

这句说明叫做“purpose string”（用途说明）。它就是 iOS 在权限请求弹窗里显示的文字。Apple 在关于[访问受保护资源](https://developer.apple.com/documentation/uikit/requesting-access-to-protected-resources)的文档里写得很清楚：如果 app 的代码访问这些资源却没有 purpose string，App Review 会拒绝。

这不是审核员拒的。这项检查是自动的，在构建交付时、进入审核之前就会触发，和隐私清单的 [ITMS-91053](https://devoria.fr/zh-hans/blog/itms-91053-missing-api-declaration-expo) 一样。这个构建会被丢弃，你得重新上传一个。

## 为什么 app 没用这项数据，Apple 还是拒了

这是最让人意外的地方。**Apple 分析的是构建里包含的代码，而不是 app 实际做了什么。**只要你打包进去的某个库引用了相册，这个键就是必需的，哪怕没有任何界面会请求访问照片。Apple 的消息里自己也说明了：外部库或 SDK 可能会引用这些 API，purpose string 依然是必填的。

我的情况发生在 2026 年 9 月 26 日。整理 Solys 的配置时，我删掉了 `NSPhotoLibraryUsageDescription` 这个键，因为 app 完全不碰照片。结果下一个构建就被 ITMS-90683 拒了。原因是：app 用到的两个 Expo 库 `expo-image` 和 `expo-file-system` 里有引用相册的代码。之前的构建能通过，只是因为那个键还在。

**教训**：说明键不能因为“用不到”就删。只有当构建里再也没有任何库引用这个 API 时，才能删。

## 最常见的键

- `NSPhotoLibraryUsageDescription`：读取或写入照片。
- `NSPhotoLibraryAddUsageDescription`：只添加照片，不读取。
- `NSCameraUsageDescription`：相机。
- `NSMicrophoneUsageDescription`：麦克风。
- `NSLocationWhenInUseUsageDescription`：使用期间的位置。
- `NSContactsUsageDescription`：通讯录。
- `NSUserTrackingUsageDescription`：广告追踪（[App Tracking Transparency](https://devoria.fr/zh-hans/blog/guideline-5-1-2-third-party-ai-att-data-sharing)）。

Apple 的文档对每个键都有说明，比如 [NSPhotoLibraryUsageDescription](https://developer.apple.com/documentation/bundleresources/information-property-list/nsphotolibraryusagedescription) 的文档：只要 app 使用了读取或写入相册的 API，就必须提供它。

## 在 Expo app 中修复 ITMS-90683

1. **记下 Apple 邮件里提到的键。**消息里会给出它的准确名称。
2. **把它加到你的配置里**，放在 `ios.infoPlist` 下，参照 [Expo 关于权限的文档](https://docs.expo.dev/guides/permissions/)：

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "Solys 不会访问你的照片。此权限永远不会被请求。"
      }
    }
  }
}
```

3. **重新构建。**Expo 明确说明：Info.plist 的修改无法通过远程更新下发，需要新的二进制文件。
4. **把构建重新上传**给 Apple，然后在你的版本里选中它。

如果你的 app 做了多语言，有个坑：语言文件只是翻译某个键，并不会声明它。这个键必须先存在于 `ios.infoPlist`（或相关插件的配置）里。否则 app 可能在第一次调用时崩溃。

## 如果 app 不用这项数据，该写什么？

Apple 要求说明准确、有用、具体。如果你的 app 真的用到了这项数据，就用一句话说清楚用途：“app 使用相机扫描你车票上的条形码。”

如果这个键只是因为某个库才需要，Apple 给了两种办法：写上说明，或者删掉访问该数据的代码。当代码来自某个库时，你没法简单地删掉它。所以在 Solys 上我写了实话：“Solys 不会访问你的照片。此权限永远不会被请求。”这是个务实的选择：下一个构建在交付时通过了，但我不能保证 Apple 永远接受这句话。

## 上传前找出缺失的键

在项目根目录运行下面这条命令，会列出 iOS 代码中引用了最受关注的那些 API 的库文件：

```bash
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
  node_modules/*/ios node_modules/@*/*/ios
```

每个名字对应一类数据：`PHPhotoLibrary` 是照片，`AVCaptureDevice` 是相机和麦克风，`CLLocationManager` 是位置，`CNContactStore` 是通讯录，`EKEventStore` 是日历，`ATTrackingManager` 是追踪。每出现一个结果，就检查你的配置里有没有对应的说明键。

这张网能兜住我遇到过的情况。但它代替不了仔细读 Apple 的邮件，邮件才是唯一可靠的清单，和 ITMS-90338 的非公开 API 一样。自从那次被拒，我每次构建前都会做这项检查：只要几秒钟，而一次 ITMS-90683 拒绝要浪费一个构建，外加重新构建的时间。

## 顺利上传你的构建

ITMS-90683 只要看懂了就能很快修好，针对 Xcode 版本的 ITMS-90725 也一样。之后来自审核员的拒绝就需要多花些心思了：处理流程见 [app 被 Apple 拒绝](https://devoria.fr/zh-hans/expertise/app-rejected-by-apple)页面，最常见的原因见 [Apple 为什么拒绝 app](https://devoria.fr/zh-hans/blog/apple-app-rejection-reasons-real-cases)。

要在上传前检查你的材料，[Apple Review Kit](https://devoria.fr/zh-hans/kits/review-apple) 汇集了我的检查清单和会审阅你项目的 Claude Code skills。如果上传卡住了，想找个人帮你看看，[和我预约一小时](https://devoria.fr/zh-hans/coaching)：我们通过视频通话，在你的屏幕上一起过你的项目。如果你正在准备第一次发布，[做一次免费诊断](https://devoria.fr/zh-hans/diagnostic)：它会帮你理清步骤顺序，并把我的 Apple 防拒清单发给你。

## 常见问题

### ITMS-90683 算是 App Review 拒绝吗？

不算人工审核员的拒绝。这是构建交付时、进入审核之前的自动检查，和图标相关的 ITMS-90717 一样。没人打开过你的 app。构建被丢弃了：你需要修改 Info.plist，然后上传一个新的。

### 为什么我的 app 没用某项数据，Apple 还要求对应的键？

因为 Apple 分析的是构建中的代码，而不是 app 的行为。只要打包进去的某个库引用了相册或相机，就必须提供说明键，哪怕没有任何界面会请求这项权限。

### 能用远程更新修复 ITMS-90683 吗？

不能。缺失的键在 Info.plist 里，而它是二进制文件的一部分。远程更新改不了这个文件：你必须重新构建，再上传给 Apple。

### 在 Expo 项目里，NSPhotoLibraryUsageDescription 加在哪里？

加在 app 配置的 `ios.infoPlist` 下，配上一句描述用途的话。有些库的插件也提供专门的设置，可能还会加入其他键，比如后台模式。无论哪种方式，这个键都必须存在于基础配置中，而不只是在翻译文件里。

### 没用到的说明键要删掉吗？

只有在构建里再也没有任何库引用相关 API 时才删。否则下次上传会被 ITMS-90683 拒绝。删除某个键之前，先在依赖项的 iOS 代码里搜一下这个 API 的名字。


## 你的项目

[Apple Review Kit](https://devoria.fr/zh-hans/kits/review-apple)：我在用的 App Store 审核检查清单、我被 Apple 拒绝后的修改、给审核员的备注，以及两个审查你 App 的 Claude Code skills。29 €。

[iOS Kit](https://devoria.fr/zh-hans/kits/ios)：用 Claude Code 做你的 iPhone App：我自己 App 的起步代码、检查其工作的 skills，以及 Apple Review Kit、App Store Screenshots Kit 和 ASO Kit。129,99 €。
