症状:构建已经上传,但 TestFlight 显示 Missing Compliance,无法继续正常分发。
最快解法:先按完整构建中的加密来源分成“通常无需上传文件、需要进一步判断、应准备材料”三路,再检查最终 Archive 里的 Info.plist,不要把 HTTPS 直接等同于复杂申报,也不要未经核查一律填“不使用加密”。
Apple 将 Missing Compliance、Invalid Binary 和 Waiting for Export Compliance Review 分列为不同的构建状态,说明它不是签名失败、二进制无效或单纯后台处理中。(Apple 构建状态说明)
这篇文章适合三类人:上传 TestFlight 构建后看到 Missing Compliance 的独立开发者;使用 HTTPS、Keychain、登录 SDK、支付 SDK 或端到端加密功能,却不确定如何回答问卷的项目维护者;以及通过远程 Mac 或持续集成反复上传构建,希望把出口合规检查固化进发布流程的小团队。
SECTION 01先按加密来源决定处理路线
出口合规判断的对象不是某一段业务代码,而是你上传的完整构建。检查范围至少应包括 App 自有代码、Apple 系统能力、静态库、动态库和第三方 SDK。
Apple 的出口合规流程会根据 App 使用、访问、包含或集成的加密能力,要求你完成问卷,或者关联已经批准的材料。(Apple 出口合规总览)
你可以先按下面的三路判断:
第一路:通常无需上传出口合规文件。
适用于 App 只调用 Apple 操作系统提供的安全能力,例如通过 URLSession 建立 HTTPS 连接、使用 Keychain 保存令牌,或调用系统安全框架完成身份验证。前提是项目没有额外嵌入系统外的加密算法、密码库或安全 SDK。
这类场景仍可能需要在 App Store Connect 中回答问卷。判断“通常无需文件”不等于可以跳过核查,更不等于可以把所有网络通信都标记为不使用加密。
第二路:需要进一步判断。
适用于第三方登录、支付、即时通信、风控、同步或数据保护 SDK 参与加密,但你还没有确认其二进制组成、实际启用功能和分发范围。
此时不要只看业务源码。如果 SDK 自带标准加密实现,或者静态库、动态库中包含独立密码库,就不能因为你没有直接调用 AES、RSA 或椭圆曲线函数而自动选择豁免。
第三路:应准备正式材料。
适用于自研加密协议、未被公认标准组织采纳的算法、专有密码库,或产品主要提供安全通信、加密存储、密码管理和隐私保护能力。
这类 App 不应通过修改 Info.plist 来绕过问卷。你需要整理技术说明、依赖组成、实际功能、分发地区及供应商材料,必要时寻求具有出口管制经验的专业人士意见。
SECTION 02只使用系统加密能力,为什么还要检查依赖
普通工具类 App 经常使用 HTTPS、Keychain 和系统身份验证接口。Apple 对相关场景提供了出口合规判断路径,但你仍然要确认没有额外实现或嵌入系统外加密。(Apple 加密出口合规文档)
真正容易出错的地方在依赖边界。你可能没有在业务源码里写加密算法,却在支付 SDK、聊天 SDK 或开源网络库中链接了独立实现。最终申报对象是上传的完整构建,而不是某个源代码目录。
建议为每次发布保留一份脱敏的加密依赖清单,至少记录:
- 依赖名称、版本号和集成方式。
- 依赖是源码包、静态库还是动态库。
- 依赖是否自行实现标准算法,还是只调用 Apple 系统框架。
- 实际启用的功能,是传输加密、数据存储加密、签名、哈希,还是端到端加密。
- SDK 供应商是否提供出口分类、合规说明或地区分发限制。
- 本次问卷答案、构建编号和必要的内部复核截图。
如果记录只能证明“项目用了 HTTPS”,却不能证明没有额外的加密库,证据链仍然不完整。不要把登录 SDK 或支付 SDK 简单归为必然豁免,也不要把所有开源加密库简单归为必然需要文件。
SECTION 03第三方标准算法和安全 SDK 怎么判断
第三方 SDK 的风险通常不在名称,而在它实际打包进了什么。一个登录 SDK 可能只调用系统 TLS,也可能自带证书固定、密钥协商、消息加密或独立密码库;一个支付 SDK 可能只负责跳转,也可能在本地加密交易数据。
你的核查顺序应当是:
- 获取 SDK 官方文档、版本说明和出口合规声明。
- 确认 SDK 是源码依赖、静态库、动态库,还是通过其他二进制包间接引入。
- 检查最终 App 包中的链接库和资源,不要只看
Package.swift、Podfile 或项目配置。 - 记录实际启用的加密功能,区分传输加密、文件加密、签名、哈希和自研协议。
- 根据 App Store Connect 问卷判断是否需要文件,不要用 SDK 的营销描述代替分类结论。
- 对美国出口和目标分发地区分别复核,不要把 Apple 的问卷结果当成覆盖所有国家的法律意见。
美国出口分类与 App Store Connect 申报不是同一件事。美国商务部工业与安全局的加密常见问题资料说明,特定产品和出口情形下可能涉及自分类或 CCATS,但是否适用要看产品、分类和出口事实。
如果你面向法国用户分发,还应单独核对法国主管机构关于加密手段使用、提供、进口、欧盟内部转移和出口的要求。法国主管机构的密码学监管说明不能替代你的项目复核,Apple 的豁免判断也不能直接当成法国法律结论。
SECTION 04自研协议和安全产品不能靠改配置绕过
以下情形不适合采取“先填 NO,之后再说”的策略:
- App 自己设计了未被公认标准组织采纳的加密协议或算法。
- App 的主要卖点是安全通信、加密云盘、密码管理、加密备份或隐私存储。
- App 内置了不透明的专有密码库,团队无法说明算法、密钥管理和功能范围。
- 第三方 SDK 提供完整端到端加密,但供应商没有给出足够的分类资料。
- App 面向多个国家发布,却没有梳理不同地区的监管要求。
你需要区分三类材料:
- Apple App Store Connect 合规材料:用于让 Apple 处理 App 的加密使用情况,并将批准信息关联到构建。
- 美国出口分类材料:用于美国出口管制体系中的分类、备案或审查流程,是否需要取决于产品和出口事实。
- 法国相关声明或许可材料:用于法国监管流程,责任主体和文件要求需要按具体操作核实。
如果团队无法解释算法、SDK 来源和实际功能,先暂停发布并补齐事实材料,比上传多个答案不一致的构建更安全。
SECTION 05TestFlight 的 Missing Compliance 怎么解除
Apple 的TestFlight 出口合规处理流程要求你进入 App Store Connect 的 TestFlight 页面,选择对应平台和构建,再进入构建详情中的 Provide Export Compliance Information。
通常有两条处理路径:
- 直接回答加密问题。如果 Apple 判断不需要文件,保存问卷答案。
- 关联已经批准的出口合规材料,等待当前构建完成相应审核状态。
Missing Compliance 表示构建缺少出口合规信息,不应与 Invalid Binary 混为一谈。前者首先需要完成问卷或材料处理,后者通常意味着构建本身没有满足上传要求。
内部测试也不要只看“构建已经上传”。如果构建详情仍显示需要采取行动,就不能把它当成已经稳定可交付的测试构建;外部测试还可能有额外审核,最终以 App Store Connect 当前页面状态为准。
SECTION 06FAQ:几个最容易卡住的判断
出现 Missing Compliance 时,内部测试还能使用这个构建吗?
Missing Compliance 表示该构建缺少出口合规信息,不能按正常完成状态处理。你应先进入 TestFlight 的构建详情,完成问卷或关联已批准材料;如果页面仍显示待处理状态,就不要把它当作可稳定分发的构建,应以 App Store Connect 当前状态为准。
App 只使用 HTTPS 和 Keychain 时,出口问卷怎么回答?
如果 HTTPS 通过 URLSession 等 Apple 系统能力实现,Keychain 也只是调用系统安全能力,通常可以按系统提供的豁免场景继续判断。但你仍需检查第三方库、静态库、动态库和实际启用功能,不能只根据业务源码直接选择不使用非豁免加密。
ITSAppUsesNonExemptEncryption 应该设置为 YES 还是 NO?
确认 App 及其依赖只使用无加密或属于豁免范围的加密时,通常设置为 NO;只要包含系统外的非豁免加密,就应设置为 YES,并根据 Apple 的审核结果配置合规代码。无法确认时,不要用 NO 规避问卷。
第三方登录或支付 SDK 使用加密,需要提交哪些材料?
先向 SDK 提供方确认其二进制是否包含标准算法、专有协议或独立加密实现,再保留版本、功能、库组成和分发地区记录。根据 App Store Connect 问卷判断是否需要材料;如果涉及美国出口分类或法国分发,还要分别复核对应主管机构的要求。
为什么配置 Info.plist 后新构建仍要求填写加密信息?
常见原因是配置没有进入最终 Archive,键名或布尔值写错,修改后没有重新归档上传,或者新构建仍由另一套 Target、Scheme 或构建脚本生成。你必须解压最终归档产物检查 Info.plist,再用递增的构建号重新上传,不能只看 Xcode 项目设置界面。
SECTION 07ITSAppUsesNonExemptEncryption 应该怎么配置
这个键是布尔值,不是文字说明,也不是“是否使用 HTTPS”的简单开关。
- 设置为
NO:你确认 App 及其第三方库不使用加密,或者只使用属于豁免范围的加密。 - 设置为
YES:你确认 App 使用非豁免加密,通常还需要根据审核结果提供合规代码。 - 不配置:App Store Connect 可能在每次新版本上传时再次引导你回答加密问卷。
Apple 的ITSAppUsesNonExemptEncryption 键说明强调,判断范围包含 App 链接的第三方库;缺少这个键时,系统可能继续引导你完成出口合规问题。
如果 Apple 审核了你的加密材料并提供代码,应配置 ITSEncryptionExportComplianceCode。这个代码不是你自己编的,也不是 Bundle ID、App ID 或 App Store Connect API Key,而是 Apple 处理合规材料后提供的结果。
确认属于豁免范围时,配置可以类似这样:
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
如果判断为非豁免加密,则不能用上面的配置规避申报,而应按 Apple 返回的结果填写:
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>
<string>你的 Apple 合规代码</string>
SECTION 08为什么配置后仍然重复询问
最常见的问题不是 Apple 没读取配置,而是配置没有进入最终上传产物。你可以按下面的顺序复核:
- 确认修改的是实际上传 Target 的
Info.plist,而不是测试 Target 或未使用的配置文件。 - 检查键名是否准确:
ITSAppUsesNonExemptEncryption,大小写和拼写都不能变。 - 确认值是 Boolean 类型,而不是字符串
"NO"或"YES"。 - 重新执行 Archive,不要只重新上传旧的
.xcarchive或旧的.ipa。 - 解压最终
.ipa,检查Payload/应用名.app/Info.plist中是否存在目标键。 - 核对上传日志中的构建号,确认 App Store Connect 展示的是刚生成的新构建。
- 如果项目有多个 Scheme、Flavor、脚本或 CI 配置,检查它们是否在归档阶段覆盖了
Info.plist。 - 新构建上传后,再回到 TestFlight 构建详情确认状态是否变化。
Apple 的上传构建说明指出,构建需要经过 Apple 系统处理后才会显示在 App Store Connect。因此“上传命令成功”不等于“构建已经完成处理”,应先区分 Processing、Missing Compliance 和其他状态。
SECTION 09把加密合规纳入远程 Mac 发布验收
你可以把下面的清单加入远程 Mac、CI 或本地发布流程。它不替代 Apple 问卷,但能避免同一个错误在每次上传时重复出现:
- ✅ 依赖清单已更新,包含静态库、动态库和第三方 SDK。
- ✅ 已记录 SDK 是否自带标准算法、专有协议或端到端加密。
- ✅ 已确认本次构建使用的 Scheme、Target 和分发地区。
- ✅ 已检查最终 Archive 中的
Info.plist,而不是只看项目设置界面。 - ✅ 已保存脱敏后的构建编号、上传入口、处理状态和问卷结果。
- ✅ 已确认 App Store Connect 中的构建状态不再是 Missing Compliance。
- ✅ 如果提交了材料,已记录当前审核状态。
- ✅ 如果使用自动上传,已确认脚本没有暴露 API Key、批准代码或账号信息。
- ✅ 已用新的构建号重新上传,避免误判为旧构建缓存。
- ✅ 已在 TestFlight 页面确认构建可以进入下一步测试或提交流程。
最终验收可以归纳为三种结果:
- 问卷人工处理即可:构建不需要材料,完成回答后状态恢复。
- 构建配置可以消除重复问询:确认豁免范围后,最终
Info.plist正确写入NO,后续构建不再反复询问。 - 必须等待材料审核:构建涉及非豁免加密,已提交文件但仍处于审核状态,此时不要通过修改键值绕过。
在远程 Mac 上操作时,日志和截图必须脱敏。账号邮箱、Bundle ID、App Store Connect API Key、出口合规批准代码、内部 SDK 名称、私有文件路径和上传日志,都不应直接贴到工单、聊天群或公开仓库中。
如果你正在搭建长期发布环境,可以先参考 MACNOX 的远程 Mac 使用入口,再把 Archive、上传与 TestFlight 状态检查纳入发布脚本。需要临时的 macOS 发布环境时,MACNOX 的 Mac 租赁方案可以作为远程 Archive、上传和验收的执行节点;但长期高负载、需要物理 USB 设备或必须完全控制硬件的团队,仍应评估自购 Mac 或自建机器。
真正导致 Missing Compliance 的,往往不是“用了 HTTPS”这么简单,而是依赖没有盘点、最终产物没有复核、问卷答案没有和构建绑定。先确认加密来源,再决定 ITSAppUsesNonExemptEncryption 和材料路径,最后用新构建验证状态;这样比反复上传同一个 Archive,或为了消除提示而盲填 NO,更稳妥。