Enhance child safety with PermissionKit
2025年6月9日
一句话判断
如果你的 app 有社交功能且用户包含未成年人,PermissionKit 是你今年必须接入的框架。它把”孩子想和某人聊天”这个请求,变成了一条 iMessage,父母直接在信息里批准或拒绝。整个流程优雅得不像 Apple 的 API(褒义)。
这场 Session 讲了什么
PermissionKit 解决的问题很具体:当一个孩子在 app 中想和一个陌生人开始通信时,app 如何安全地获取父母的许可?
核心流程:
- App 检测到当前用户是孩子,且对方是未知联系人。
- App 创建一个
PermissionQuestion,附带CommunicationTopic(包含对方的 handle、姓名、头像、通信方式如 message/call/video)。 - 系统在 Messages 中打开一个预填好的消息窗口,收件人是 Family Sharing 组中的父母/监护人。
- 父母收到消息后可以直接 decline 或 review(review 会显示更多上下文信息),做出 approve 或 decline 决定。
- 父母的决定自动通知孩子,同时在后台送达你的 app。
判断用户是否为孩子的两种方式: 用你自己的账号系统,或者用新的 Declared Age Range API(父母可以允许孩子分享年龄范围)。
UI 适配: 对孩子的账户,默认隐藏未知联系人的消息预览、头像等内容。用 CommunicationLimits.knownHandles(in:) 做批量查找,返回已知 handle 的子集。
SwiftUI 集成: CommunicationLimitsButton 直接在 SwiftUI 视图中使用,点击触发系统流程。UIKit 用 CommunicationLimits singleton 配合 UIViewController。AppKit 配合 NSWindow。
异步响应处理: 通过 CommunicationLimits singleton 的 AsyncSequence 持续监听父母的审批结果。App 会以 background launch 方式唤醒。
值得深挖的点
前提条件很明确。 用户必须在 Family Sharing 组中,且父母必须开启了 Communication Limits。不满足任何一个条件,API 返回默认响应(通常是拒绝)。这意味着 PermissionKit 不适用于所有场景——你的 app 需要有 fallback 方案。
metadata 越丰富越好。 你在 CommunicationTopic 中提供的 PersonInformation(姓名、头像)会直接展示给父母。信息越充分,父母越容易做出判断。但注意隐私——不要过度收集对方的信息。
Ask Flow 有两种入口。 除了发消息给父母,还有一个 “in-person” 选项:孩子可以让父母当面输入 Screen Time 密码直接批准。这适合父母就在旁边的情况。
后台启动的时机。 父母回复时你的 app 被 background launch,但不要在这个时机做重度操作。拿到响应后更新本地缓存和 UI,必要时同步到服务器。
代码片段
创建 PermissionQuestion 发送给父母:
import PermissionKit
// 构建通信主题
let person = PersonInformation(
handle: "unknown_user@example.com",
name: "张三",
image: someImageData
)
let topic = CommunicationTopic(
people: [person],
actions: [.message]
)
// 创建问题
let question = PermissionQuestion(topic: topic)
// SwiftUI 中使用
CommunicationLimitsButton(question: question) {
Label("请求与 \(person.name) 通信", systemImage: "bubble.left")
}
后台监听父母的响应:
Task {
for await response in CommunicationLimits.shared.responses {
switch response.decision {
case .approved:
// 更新 UI,允许通信
updateUI(allowCommunication: true)
case .declined:
updateUI(allowCommunication: false)
}
// 同步到你的服务器
try await syncToServer(response)
}
}
过滤已知联系人:
let knownHandles = try await CommunicationLimits.shared.knownHandles(
in: Set(messageThreads.map(\.handle))
)
// 只对已知 handle 显示消息预览
最佳实践
只对确认是孩子的用户展示 PermissionKit 流程。 误用(对成人用户展示)会让用户体验变差且可能违反 App Store 审核规则。Declared Age Range API 是判断年龄的推荐方式。
提供丰富的 metadata。 对方的姓名和头像会显著提升父母的审批意愿和决策质量。但只收集你合法拥有的信息。
不要依赖 PermissionKit 做唯一的安全机制。 它是 Apple 生态内的解决方案。跨平台场景(你的 web 版、Android 版)需要你自己实现类似逻辑。把 PermissionKit 的审批结果同步到你自己的服务器,作为统一的权限来源。
处理好”没有 Family Sharing”的情况。 API 会返回默认响应,但你应该在 UI 上告诉用户发生了什么,而不是静默失败。
还有什么值得关注
- 配套 API:Sensitive Content Analysis 扩展到实时视频通话中的裸露内容检测。Screen Time Framework 和 Family Controls Framework 也有更新。
- PermissionKit 目前只支持 iOS 26 / iPadOS 26 / macOS 26。老版本系统需要你自己实现类似的审批流程。
- 配套视频:“Deliver age-appropriate experiences in your app” 讲了 Declared Age Range API 的详细用法。