其他
在 iOS/iMessage…
当应用需要让儿童就联系人通信限制向家长/监护人发送审批请求并接收批准/拒绝结果时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15
适用场景
在 iOS/iMessage 中为儿童通特定
解决思路
- 导入 PermissionKit;不要自造 PermissionKit entitlement keys;在添加 signing requirements 前核对当前 Apple 文档和 Xcode capabilities。
- 按集中版本矩阵核对当前 SDK:Core APIs(Topics、handles、questions、responses、choices、CommunicationLimits)适用于 iOS/iPadOS/Mac Catalyst/macOS/visionOS 26.0+;Errors(AskError)适用于 26.1+;Presentation(AskCenter、ask/response sequences、PermissionButton、significant-update topics)适用于 26.2+。
- 按流程实现:儿童在 app 中遇到通信限制;app 创建描述请求的 PermissionQuestion;系统向儿童展示问题以便发送给家长;家长审核并批准或拒绝;app 收到带家长决定的 PermissionResponse。
- 使用 AskCenter 单例管理权限请求和响应。
- 使用 PermissionQuestion 描述正在请求的权限。
- 使用 PermissionResponse 表示家长决定(批准或拒绝)。
- 使用 PermissionChoice 表示具体答案(approve/decline)。
- 使用 PermissionButton 作为触发权限流程的 SwiftUI 按钮。
- 使用 CommunicationTopic 表示通信相关权限请求主题。
- 使用 CommunicationHandle 表示电话号码、email 或自定义标识。
- 使用 CommunicationLimits 检查系统已知哪些通信 handles。
- 使用 SignificantAppUpdateTopic 表示重大 app 更新权限请求主题。
- 使用 CommunicationLimits.current 检查系统是否已知道 app 的某个 communication handle;这不是通信限制是否启用的探针。
- 如果限制未启用,AskCenter.shared.ask(_:in:) 会抛 AskError.communicationLimitsNotEnabled;提问时处理该路径。
- knownHandles(in:) 要求调用 app 有非 nil、非空 bundle identifier;调用前 guard Bundle.main.bundleIdentifier。
- 需要判断是否需要权限提示时,取 let limits = CommunicationLimits.current,调用 await limits.isKnownHandle(handle),返回 !isKnown。
- 批量过滤已知 handles 时,先 guard Bundle.main.bundleIdentifier?.isEmpty == false else { return [] },再取 CommunicationLimits.current,返回 await limits.knownHandles(in: handles)。
- 创建 phone handle:CommunicationHandle(value: +1234567890, kind: .phoneNumber)。
- 创建 email handle:CommunicationHandle(value: friend@example.com, kind: .emailAddress)。
- 创建 custom handle:CommunicationHandle(value: user123, kind: .custom)。
- 为单个联系人创建问题:用 CommunicationHandle 构造 PermissionQuestion<CommunicationTopic>(handle: handle)。
- 为多个联系人创建问题:构造 handles 数组,然后 PermissionQuestion<CommunicationTopic>(handles: handles)。
- 使用 CommunicationTopic.PersonInformation 提供 display names 和 avatars,构造时传入 handle、nameComponents、avatarImage。
- 构造 CommunicationTopic 时传入 personInformation: [personInfo] 和 actions: [.message, .audioCall],再用 PermissionQuestion<CommunicationTopic>(communicationTopic: topic)。
- 通信 action 使用 .message 表示文本消息。
- 通信 action 使用 .audioCall 表示语音通话。
- 通信 action 使用 .videoCall 表示视频通话。
- 通信 action 使用 .call 表示通用通话。
- 通信 action 使用 .chat 表示聊天通信。
- 通信 action 使用 .follow 表示关注用户。
- 通信 action 使用 .beFollowed 表示允许被关注。
- 通信 action 使用 .friend 表示好友请求。
- 通信 action 使用 .connect 表示连接请求。
- 通信 action 使用 .communicate 表示通用通信。
- 用 AskCenter.shared 请求儿童将 permission question 发送给家长或监护人。
- 异步 ask 调用启动发送流程;家长决定稍后通过 responses(for:) 到达。
- 如果儿童取消发送流程,系统不会为该 question 交付 PermissionResponse。
- 在 requestPermission 中 do 调用 try await AskCenter.shared.ask(question, in: viewController),启动问题发送流程后另行等待 responses(for:)。
- catch AskError 时区分 .communicationLimitsNotEnabled:通信限制未激活,继续正常 app 流程。
- catch .contactSyncNotSetup:联系人同步未配置。
- catch .invalidQuestion:问题格式错误。
- catch .notAvailable:此设备上 PermissionKit 不可用。
- catch .systemError(let underlying):打印 System error 与 underlying。
- catch .unknown:处理未知错误。
- catch @unknown default:处理未来未知 case。
- 使用 PermissionButton SwiftUI view 在点击时触发权限流程;它使用与 AskCenter 相同的 response model。
- 观察 responses 并建模 pending/canceled state,不要假设每次点击都会产生家长决定。
- SwiftUI 示例中创建 handle,body 中创建 PermissionQuestion<CommunicationTopic>(handle: handle),并用 PermissionButton(question: question) { Label(Ask to Message, systemImage: message) }。
- 对更丰富的 SwiftUI flows、自定义 topics、长生命周期 managers,阅读 references/permissionkit-patterns.md。
- 异步监听 permission responses;按 question.id 跟踪 pending questions。
- 给 UI 提供 retry 或 expiration 路径,因为儿童可取消 iMessage 发送流程而不产生 response。
- 组合 known-handle checks 与 response handling 时,沿用 knownHandles(in:) 的 bundle identifier guard。
- 定义 PermissionRequestState 为 pending、approved、denied、expired,并用 var requestStates: [UUID: PermissionRequestState] = [:] 跟踪。
- 实现 expireIfStillPending(_ id: UUID):guard requestStates[id] == .pending else { return },设为 .expired,并重新启用 asking 或展示 retry/canceled UI。
- 实现 observeResponses():取 let responses = AskCenter.shared.responses(for: CommunicationTopic.self),遍历 for await response in responses,取 response.choice 和 response.question。
- 在 response 的 switch choice.answer 中,.approval 时设 requestStates[question.id] = .approved,并打印 Approved for topic 与 question.topic。
- 在 response 的 switch choice.answer 中,.denial 时设 requestStates[question.id] = .denied,并打印 Denied。
- 在 response 的 switch choice.answer 中,@unknown default 时 break。
- 使用 PermissionChoice properties:response.choice 的 answer(.approval 或 .denial)、id、title。
- 使用便利静态值 PermissionChoice.approve 和 PermissionChoice.decline。
- 对需要家长批准的重大 app 更新使用 SignificantAppUpdateTopic 请求权限。
- 你的 app 根据适用法规决定什么算 significant,并咨询合格法律顾问解释合规。
- 使用简洁、易懂的描述,说明家长正在批准的具体变更。
- 构造 SignificantAppUpdateTopic(description: This update adds multiplayer chat features),再构造 PermissionQuestion<SignificantAppUpdateTopic>(significantAppUpdateTopic: updateTopic)。
- 调用 try await AskCenter.shared.ask(question, in: viewController),设 requestStates[question.id] = .pending,并 scheduleExpiration(for: question.id)。
- 监听 AskCenter.shared.responses(for: SignificantAppUpdateTopic.self);.approval 时继续更新并设 approved,.denial 时跳过更新并设 denied。
- 若 pending window 到期前没有响应,保持更新阻塞或提供 retry;儿童取消不会产生 denial response。
- 避免把 known-handle lookup 当作 limits enabled 的证明;应将 ask operation 的 .communicationLimitsNotEnabled 作为正常未配置路径处理。
- 避免把 AskError 折叠成一条消息;区分 limits-disabled、contact-sync、invalid-question、unavailable、system、unknown 情况。
- 避免 question 没有 handle 或 person information;展示前验证至少一个 meaningful communication target。
- 避免 ask 后 fire-and-forget;观察 response 和 pending state,同时允许儿童取消/放弃。
- 避免使用已弃用的 CommunicationLimitsButton;改用 PermissionButton。
- 选择 PermissionKit 前理解 iMessage-only routing。
- 将 centralized availability matrix 应用于每个使用的 API。
- 创建 CommunicationHandle 时使用正确 Kind(phone、email、custom)。
- Known-handle 示例在 knownHandles(in:) 前 guard 非 nil、非空 bundle identifier。
- Person information 包含 name components,以清楚显示 permission prompt。
- Communication actions 匹配 app 实际通信能力。
- Response handling 在 main actor 更新 UI。
- Error states 给用户清晰指引。
- 阅读扩展模式(response handling、multi-topic、UIKit)参考 references/permissionkit-patterns.md。
- 查阅 References 中的 PermissionKit framework、AskCenter、PermissionQuestion、PermissionButton、PermissionResponse、CommunicationTopic、CommunicationHandle、CommunicationLimits、SignificantAppUpdateTopic、AskError 和 Creating a communication experience 文档。
适用边界 · 注意事项
- 不要把它当作通用 in-app 联系人权限、审核或聊天安全框架;PermissionKit communication experiences 仅用于家长/监护人审批流程。
- 仅在 iMessage 可用的 communication experiences 中适用,不能用于没有 iMessage 或非 Apple 平台的一般通信权限。
- 需要 PermissionKit、对应 iOS/iPadOS/Mac Catalyst/macOS/visionOS 版本和 Xcode capabilities;缺少这些 Apple 平台/工具/账号条件时不适用。