Files
keyboard/docs/app-store-final-readiness-2026-03-08.md
2026-03-09 17:34:08 +08:00

396 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# KeyBoard 提审最终检查清单
更新时间2026-03-08
适用目标2026-03-09 准备提交 Apple App Store 审核
## 一、当前结论
基于当前代码、工程配置以及 Apple 截至 2026-03-08 的公开规则,这个项目现在不是“不能上”,而是仍然存在几项会明显拉低一次过审率的阻塞点。
如果今天不补,最可能的拒审方向仍然是:
1. `2.1 App Completeness`
2. `5.1.1 Data Collection and Storage`
3. `2.3.1 Accurate Metadata`
4. `1.2 User-Generated Content`
5. `3.1.2` / 订阅展示不完整
## 二、当前发现的问题
下面按严重程度排序。
### P0法律文档仍是“未发布正式版”的回退状态
证据:
1. [KBConfig.h](/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBConfig.h#L76) 中 3 个正式 URL 仍然是空字符串:
- `KB_TERMS_OF_SERVICE_URL`
- `KB_PRIVACY_POLICY_URL`
- `KB_MEMBERSHIP_AGREEMENT_URL`
2. [KBWebViewViewController.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/WebView/KBWebViewViewController.m#L273) 到 [KBWebViewViewController.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/WebView/KBWebViewViewController.m#L284) 的内置 HTML 明确写着:
- `Replace this fallback page ... before App Store submission`
- `Built-in fallback document. Configure the final public URL ...`
风险:
1. 审核员点进协议/隐私/会员协议页面后,看到的是明显占位性质的回退文案。
2. 这会直接伤到:
- `2.1 App Completeness`
- `2.3.1 Accurate Metadata`
- `5.1.1`
解决方案:
1. 今天必须把 3 个 URL 换成正式线上地址。
2. 正式页面必须可公开访问,不需要登录,不是占位页。
3. 页面正文必须和真实数据流、App Privacy、Review Notes 完全一致。
结论:
这是当前最明确、最直接的提审阻塞项。
### P0隐私披露与当前代码能力相比明显不完整
证据:
1. 主 App 的 [PrivacyInfo.xcprivacy](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/PrivacyInfo.xcprivacy#L9) 目前只声明:
- `EmailAddress`
- `UserID`
- `OtherUserContent`
2. 键盘扩展的 [PrivacyInfo.xcprivacy](/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/PrivacyInfo.xcprivacy#L9) 目前只声明:
- `OtherUserContent`
3. 但代码中已经能确认至少还涉及:
- 语音录音上传转写
[KBAIHomeVC.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m#L1238)
[AiVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VM/AiVM.m#L271)
- 头像上传
[KBMyVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VM/KBMyVM.m#L362)
- 购买记录 / 钱包流水
[KBMyVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VM/KBMyVM.m#L220)
- Release 下 Bugly 崩溃收集
[AppDelegate.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/AppDelegate.m#L93)
- 可配置的埋点上报器
[KBMaiPointReporter.h](/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBMaiPointReporter.h)
风险:
1. 代码实际行为、隐私政策、App Store Connect `App Privacy` 如果不一致,会非常容易被 `5.1.1` 打回。
2. 对你这种“自定义键盘 + Full Access + AI + 语音”的组合,这一项是审核重点。
解决方案:
1. 今天必须做一张内部数据流表,确认以下数据到底是否收集、是否上传、是否保存、是否关联账号:
- `Audio Data`
- `Other User Content`
- `Photos or Videos`
- `Purchase History`
- `Crash Data`
- `Product Interaction`(如果 Release 真开埋点)
2. 用这张表同时更新:
- 隐私政策
- App Store Connect `App Privacy`
- 必要时更新 `PrivacyInfo.xcprivacy`
3. 如果你拿不准 Bugly 和埋点,就先按“更保守的披露口径”处理。
结论:
这是当前第二个明确阻塞项,而且是被 Apple 追问概率非常高的一项。
### P0键盘 `Full Access` 的用户可见披露仍然太泛
证据:
1. 键盘扩展开启了 `RequestsOpenAccess = true`
[CustomKeyboard/Info.plist](/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Info.plist#L21)
2. 当前引导文案还是:
`Turn on Allow Full Access to experience all features`
[KBFullAccessGuideView.m](/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/View/KBFullAccessGuideView.m#L50)
3. 但代码里已经存在:
- 联网 AI 功能
- 登录态依赖
- 语音相关功能
- 订阅能力
风险:
1. Apple 对第三方键盘的 `Full Access` 审核比普通 App 更敏感。
2. 如果你只是告诉用户“开权限体验全部功能”,但没说清楚会发生什么,审核员会继续追问:
- 开了 Full Access 后会不会上传输入内容
- 哪些功能必须依赖 Full Access
- 语音会不会上传服务器
解决方案:
1. App 内用户可见文案要补充说明:
- 只有主动使用 AI / 语音 / 账号 / 订阅等联网能力时,相关数据才可能发送到服务器处理
2. 隐私政策也要写同样的口径。
3. Review Notes 必须单独解释:
- 为什么键盘需要 Full Access
- 哪些功能离不开 Full Access
- 不开启时会看到什么
结论:
这项如果不补清楚,即使代码能跑,也很容易被当成隐私说明不足。
### P1语音链路已经是“上传转写”不能再按“仅本地语音输入”口径描述
证据:
1. 录音结束后会调用转写接口:
[KBAIHomeVC.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m#L1238)
2. `AiVM` 里明确存在上传音频文件并转写:
[AiVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VM/AiVM.m#L226)
[AiVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VM/AiVM.m#L271)
3. 主 App 和扩展都声明了麦克风权限:
[Info.plist](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Info.plist#L23)
[Info.plist](/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Info.plist#L9)
风险:
1. 如果你后台和隐私政策没有按 `Audio Data` 相关能力申报,这会构成明显不一致。
2. 现在权限默认文案已经改成更准确的英文,但这还不够;审核员更看重“你有没有明确说明上传转写”。
解决方案:
1. 隐私政策里明确写:
- 语音是否上传
- 是否只用于转写
- 是否保存原始音频
- 是否用于训练
2. App Store Connect `App Privacy` 重新核对 `Audio Data`
3. Review Notes 中说明“语音输入会调用服务端转写”
### P1AI 内容安全有举报,但缺少可见的前置审核/拦截证据
证据:
1. 举报入口是存在的:
[AIReportVC.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VC/AIReportVC.m#L467)
2. 举报接口也存在:
[AiVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/AiTalk/VM/AiVM.m#L870)
3. 但从当前代码里,没有看到足够明确的 AI 输出前置审核或策略拦截证据。
风险:
1. Apple 对 AI / 聊天 / persona 这类内容,会从 `1.1``1.2` 的角度看你是否有治理能力。
2. 只有举报,没有审核/拦截说明,通常不够稳。
解决方案:
1. 你需要和后端确认:是否存在服务端内容审核。
2. 如果有Review Notes 里写清楚:
- 有内容过滤
- 有举报
- 有处理机制
3. 如果没有,建议先补服务端审核兜底再提。
结论:
这是“中高风险但代码里不一定能完全解决”的问题,取决于你后端现在是否已经有审核。
### P1Review Notes、测试账号、审核路径说明无法从工程内验证
风险:
1. 这是键盘类 App 的典型拒审来源,不在代码里,但对过审非常关键。
2. 审核员如果没走对路径,会直接判:
- 功能不可用
- 无法完成登录
- 无法完成购买
解决方案:
1. 你必须在 App Store Connect 手工准备:
- 测试账号
- 启用键盘步骤
- 开启 Full Access 步骤
- 登录步骤
- AI 使用路径
- 购买和恢复购买路径
- 哪些操作会拉起主 App
结论:
这项虽然不是代码 bug但如果你明天就提这是必须完成的外部阻塞项。
## 三、当前已具备的正向项
这些不是问题,属于可加分或至少不拖后腿的项:
1. 账号注销能力存在
[KBCancelAccountVC.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VC/KBCancelAccountVC.m#L82)
[KBMyVM.m](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VM/KBMyVM.m#L519)
2. 订阅管理能力存在
[StoreKitService.swift](/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Pay/StoreKit2Manager/Internal/StoreKitService.swift#L823)
3. 协议入口已经打通,不再是空实现
4. 麦克风权限 fallback 文案已经统一成准确英文
5. AI 举报链路存在
## 四、明天前必须完成的清单
下面这部分按“必须完成 / 最好完成”分。
### A. 必须完成
#### A1. 正式法律文档上线
- [ ] 填写 `KB_TERMS_OF_SERVICE_URL`
- [ ] 填写 `KB_PRIVACY_POLICY_URL`
- [ ] 填写 `KB_MEMBERSHIP_AGREEMENT_URL`
- [ ] 真机点开 3 个页面,确认不是 fallback HTML
- [ ] 浏览器外部访问 3 个 URL确认审核员在外部也能打开
#### A2. 隐私披露一致化
- [ ] 确认 `Audio Data` 是否收集、是否保存
- [ ] 确认键盘 AI 输入文本是否会上传、是否保存
- [ ] 确认头像上传是否需要申报 `Photos or Videos`
- [ ] 确认购买记录 / 订阅状态是否申报 `Purchase History`
- [ ] 确认 Release 下 Bugly 是否视为 `Crash Data`
- [ ] 如果 Release 开启埋点,确认是否申报 `Product Interaction`
- [ ] 完成 App Store Connect `App Privacy` 填写
- [ ] 确保隐私政策正文和后台填写一致
#### A3. Full Access 和语音说明补清楚
- [ ] 在 App 内明确说明 Full Access 与联网功能关系
- [ ] 明确说明语音会进行服务器转写
- [ ] Review Notes 解释 Full Access 的必要性和作用边界
#### A4. Review Notes 和测试账号准备完成
- [ ] 提供审核账号
- [ ] 写清启用键盘路径
- [ ] 写清打开 Full Access 路径
- [ ] 写清登录路径
- [ ] 写清购买路径
- [ ] 写清恢复购买路径
- [ ] 写清哪些操作会拉起主 App
### B. 最好今天也完成
- [ ] 后端确认 AI 内容审核是否已开启
- [ ] Review Notes 里写明有举报和内容治理机制
- [ ] 检查商店描述里是否有夸大键盘能力的文案
- [ ] 核对订阅名称、周期、价格、试用和 App Store Connect 一致
## 五、今晚的检查方案
建议按下面顺序做,不要乱跳。
### 第 1 轮:配置检查
目标:先排除“点进去就是错的”问题。
步骤:
1. 检查 3 个法律文档 URL 是否已经填正式地址
2. 检查主 App 和扩展的 `Info.plist` 权限文案
3. 检查 `PrivacyInfo.xcprivacy`
4. 检查 Release 配置下是否保留 Bugly / 埋点
通过标准:
1. 没有 fallback URL
2. 没有 placeholder 文案
3. 没有明显和真实行为冲突的隐私声明
### 第 2 轮:真机功能链路检查
目标:按审核员路径完整走一遍。
步骤:
1. 卸载旧包,重新安装
2. 首次启动
3. 注册 / 登录
4. 启用键盘
5. 打开 Full Access
6. 进入任意聊天/输入场景,切换到你的键盘
7. 触发 AI 功能
8. 触发语音功能
9. 从键盘拉起主 App 登录
10. 从键盘拉起主 App 购买
11. 恢复购买
12. 打开隐私政策 / 服务条款 / 会员协议
13. 注销账号
通过标准:
1. 整条路径没有卡死、空白页、无响应
2. 所有异常都有用户能理解的提示
### 第 3 轮:异常场景检查
目标:避免审核员踩到异常直接拒审。
步骤:
1. 未登录时进 AI
2. 未开 Full Access 时进联网能力
3. 断网时使用 AI / 购买 / 登录
4. 服务端返回错误时看提示是否明确
5. IAP 商品加载失败时看是否有兜底
通过标准:
1. 不出现无提示失败
2. 不出现 reviewer 无法理解的状态
### 第 4 轮:提审物料检查
目标:把代码外的审核材料准备齐。
步骤:
1. 完成 App Store Connect `App Privacy`
2. 准备 Review Notes
3. 准备测试账号
4. 检查商店截图和描述
5. 检查订阅商品配置
通过标准:
1. 审核员不需要猜你产品流程
2. 元数据和真实能力一致
## 六、明天提审当天的执行顺序
建议顺序:
1. 先确认线上法律文档已经发布
2. 再核对 App Store Connect 的 `App Privacy`
3. 再写 Review Notes
4. 再做一次真机完整走查
5. 最后 Archive / 上传 / 提交审核
不要反过来先提交再补文案。
## 七、我给你的最终判断
如果你明天提审之前把下面 4 件事补完:
1. 正式法律文档 URL 与正文
2. App Privacy 与隐私政策完全对齐
3. Review Notes + 测试账号
4. Full Access / 语音上传 / AI 内容安全说明
这次的送审质量会比你现在直接提交高很多。
如果这 4 件事中有 2 件以上没完成,我不建议明天直接提。
## 八、官方参考
1. App Review Guidelines
https://developer.apple.com/app-store/review/guidelines/
2. App Privacy Details
https://developer.apple.com/app-store/app-privacy-details/
3. App PrivacyApp Store Connect Help
https://developer.apple.com/help/app-store-connect/reference/app-privacy
4. Offering account deletion in your app
https://developer.apple.com/support/offering-account-deletion-in-your-app/
5. Custom Keyboard Guide
https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/CustomKeyboard.html