What’s new in privacy
Privacy & Security 进阶 20m

隐私保护新动向

What’s new in privacy

2024年6月10日

在 Apple 官方观看视频

一句话判断

iOS 18 用”进程外选择器”(out-of-process picker)的思路把隐私控制做到了极致——你的 App 永远看不到完整数据,只能拿到用户主动选中的那一条。

这场 Session 讲了什么

苹果对隐私的推进从来不是靠口号,而是靠 API 设计。iOS 18 和 macOS Sequoia 延续了”最小化数据暴露”的路线,核心思路是把”全量授权”变成”精准选择”。

今年有三个新的数据选择器值得关注:FinanceKit 的交易选择器让用户只分享特定的金融交易记录,而不是整个银行流水;Image Playground API 的图片生成选择器让 App 只拿到最终选定的图片,生成过程完全由系统托管;AccessorySetupKit 把蓝牙配对、Wi-Fi 连接、设备确认三个权限弹窗合并成一个选择器,App 只能访问已配对的设备。

平台级的变化同样不小:Private Wi-Fi 在 iOS 上实现了 MAC 地址轮换、在 macOS 上首次引入了 MAC 地址保护;蓝牙权限变得更细粒度,App 不再默认获得全量扫描能力;通讯录权限的弹窗文案也更明确了。

值得深挖的点

AccessorySetupKit:一次点击取代三个权限弹窗

之前的蓝牙配件配对流程是个灾难——用户要面对蓝牙配对弹窗、Wi-Fi 网络加入弹窗、蓝牙确认弹窗,三个弹窗各有各的困惑。更糟的是,蓝牙权限一旦授予,App 就能持续扫描周围所有蓝牙设备,这对隐私是过度暴露。

AccessorySetupKit 的设计哲学跟 Photos picker 一脉相承:系统渲染一个进程外的选择器,App 看不到选择过程,只能拿到结果。用户在列表里点选要配对的设备,系统自动处理蓝牙配对和 Wi-Fi 连接,App 获得该设备的通信权限——仅此而已。

配对完成后的权限隔离也做得精准:App 只能通过蓝牙连接已配对的设备,不能扫描未配对的设备。用户在设置里可以随时取消配对,权限立刻回收。App 还可以重命名配件、附加资产,这些管理能力是之前蓝牙 API 没有的。

这个方案对用户和开发者是双赢——用户少了困惑和恐惧,开发者少了”被拒绝权限”的流失。

FinanceKit 的两层访问控制

金融数据的敏感度比照片更高。FinanceKit 提供了两种访问机制,分别对应不同的使用场景。

Transaction Picker 是单次选择模式——用户手动勾选要分享的交易记录,App 只拿到这些。适合报销类 App,用户只想分享差旅消费,不想暴露个人购物记录。不需要申请特殊 Entitlement,直接调用。

Ongoing Access 是持续访问模式——用户选择要分享的账户并设置最早分享日期,App 持续收到该日期之后的新交易。适合记账类 App。但这个模式需要申请 FinanceKit Entitlement,审核更严格。

两层设计的聪明之处在于:它不是一刀切的”允许/拒绝”,而是让用户精确控制”分享哪些数据、从什么时候开始、是单次还是持续”。这种精细度远超传统的权限弹窗。

代码片段

AccessorySetupKit 配对蓝牙设备

// 不需要蓝牙权限弹窗,用户直接选择设备
let picker = AccessorySetupKit.Session()
let descriptor = AccessoryDescriptor(
    name: "My Camera",
    bluetoothIdentifier: UUID(/* ... */)
)
// 用户选中设备后,App 自动获得该设备的蓝牙和 Wi-Fi 访问权限
let result = try await picker.pickAccessory(matching: descriptor)
// result 包含配对完成的设备信息

场景:相机 App 需要同时连接设备的蓝牙和 Wi-Fi 热点。以前要三个弹窗,现在一个选择器搞定。坑:配对后 App 只能访问这一个设备,如果用户换了一台相机需要重新配对。

FinanceKit Transaction Picker

// 让用户选择特定的交易记录分享给 App
let picker = FinanceKit.TransactionPicker()
let transactions = try await picker.present()
// 只拿到用户手动选中的交易,不会暴露完整流水
for transaction in transactions {
    processExpense(transaction)
}

场景:报销 App 让用户从 Apple Card 交易中选择差旅消费。坑:Transaction Picker 是一次性选择,用户关闭后需要重新调用。

Image Playground API

// 图片生成过程由系统托管,App 只拿到最终结果
let playground = ImagePlaygroundViewController()
playground.delegate = self
present(playground, animated: true)

func playgroundDidFinish(_ controller: ImagePlaygroundViewController,
                          result: ImagePlaygroundResult) {
    // 只拿到用户最终选择的图片
    let selectedImage = result.image
}

场景:App 需要用户生成一张图片(头像、封面等),用系统内置的 AI 生图能力,不需要自己训练模型。坑:生成过程可能需要几秒,建议加 loading 状态。

最佳实践

已有项目迁移:如果你有蓝牙配件配对功能,AccessorySetupKit 应该立刻排上迁移计划。它不只是隐私升级,用户体验也大幅提升。金融类 App 如果已经用了其他支付数据源,可以考虑增加 FinanceKit 作为 Apple Card 用户的数据通道。

新项目起步:所有涉及敏感数据(照片、通讯录、金融交易、蓝牙设备)的场景,优先使用 Picker 模式而不是全量权限。Image Playground API 适合需要图片生成的场景,省去了自建模型的成本。Private Wi-Fi 的 MAC 地址轮换是系统级行为,不需要你做任何适配,但你的 App 如果依赖 MAC 地址做设备识别,需要改用其他方案。

还有什么值得关注

  • macOS Sequoia 首次引入了 Private Wi-Fi 的 MAC 地址保护,之前这个功能只有 iOS 有。
  • iOS 18 的蓝牙权限更细粒度了——App 不再默认获得全量扫描能力,需要在 Info.plist 里声明具体用途。
  • 联系人权限弹窗的文案变得更明确,用户能清楚知道”分享的是哪些字段”,这可能会降低授权率,要做好用户引导。
WWDC 2024