WWDC Quick Look 💓 By SwiftGGTeam
Support local network privacy in your app

Support local network privacy in your app

观看原视频

Highlight

iOS 14 为 App 直接访问本地网络增加用户授权;当 App 使用 Bonjour、单播、多播或广播查找附近设备时,开发者要在 Info.plist 写明用途并声明 Bonjour 服务类型,否则本地发现流程会被权限系统阻断。

核心内容

很多 App 都把本地网络当成默认可用的环境。用户点一下灯泡开关,手机就去找智能家居设备;玩家想开一局附近对战,App 就开始用 Bonjour 搜索同一网络里的服务;相机、打印机、路由器管理工具也会直接和局域网设备通信。iOS 14 之前,这些动作常常发生在后台,用户很难知道哪个 App 正在查看家里有哪些设备。

Apple 在这场 session 里先解释了隐私原因。本地网络里的设备组合很独特,足以形成位置线索;设备控制也有敏感性,能管理相机的 App 应该可以同步照片,别的 App 不该随便探测同一个设备。iOS 14 因此把本地网络访问放进系统权限里,让用户决定哪些 App 可以发现和连接附近设备。

这项权限只影响 App 自己直接访问本地网络的行为。只访问公网资源的 App 不需要额外处理;通过 AirPrint、AirPlay、AirDrop 或 HomeKit 这样的系统服务完成设备发现,也不需要自己管理本地网络权限。直接使用 Bonjour、单播、本地多播或广播协议时,App 就要更新配置和体验。

演示用的是一个 iOS 13 年代写的 TicTacToe App。它重新用 iOS 14 SDK 构建后,启动时看不到附近玩家,调试输出里出现 NoAuth。修复点落在 Info.plist:补上本地网络用途说明和 Bonjour service type。补齐之后,系统会在 App 真正开始浏览 Bonjour 服务时弹出本地网络权限提示。

详细内容

本场没有官方 code snippets。下面的代码块只整理逐字稿明确提到的配置项、权限边界和 API 行为,用来帮助你检查现有 App。

1. 判断哪些访问会触发权限

03:16)如果 App 只访问公网资源,或者通过系统服务完成设备发现,就不用为 iOS 14 的本地网络权限改代码。直接访问局域网时,权限系统才会介入。

不需要 App 自己处理本地网络权限:
- 只访问 wide internet 上的资源
- AirPrint
- AirPlay
- AirDrop
- HomeKit

需要本地网络权限:
- App 内直接使用 Bonjour 浏览或广播服务
- 直接访问本地单播地址
- 使用自定义 multicast 协议
- 使用自定义 broadcast 协议

关键点:

  • AirPrint、AirPlay、AirDrop、HomeKit 会由系统处理设备发现,App 不会拿到完整设备列表。
  • 直接使用 unicast、multicast 或 broadcast 访问本地网络时,App 需要获得用户许可。
  • 如果第三方 framework 在你的进程里访问本地网络,系统权限仍然归到你的 App 名下。

2. 在 Info.plist 中声明用途和 Bonjour 服务

05:24)iOS 14 要求 App 提供两个 Info.plist 信息:本地网络用途说明,以及 Bonjour 浏览或广播时使用的 service type 列表。演示中的 TicTacToe App 只使用一个服务类型,逐字稿里的值是 tictactoe.tcp

<key>NSLocalNetworkUsageDescription</key>
<string>TicTacToe uses the local network to discover players around you.</string>

<key>NSBonjourServices</key>
<array>
  <string>tictactoe.tcp</string>
</array>

关键点:

  • NSLocalNetworkUsageDescription 会出现在系统权限弹窗里,应该说明哪个具体功能需要本地网络。
  • NSBonjourServices 只列出 App 实际浏览或广播的 Bonjour service type。
  • 如果 App 缺少这些配置,演示里的 Bonjour browser 会返回 NoAuth,并且不会先显示本地网络权限弹窗。

3. 少数发现方式需要额外 entitlement

06:18)Apple 特别点出两类 App:一种不用 Bonjour 做本地 multicast discovery,另一种需要枚举网络上的所有 Bonjour service type。这两类操作在 iOS 14 需要通过 developer portal 申请 entitlement。

Info.plist 声明适用:
- 使用 Bonjour 浏览已知 service type
- 使用 Bonjour 广播自己的 service type

需要申请 entitlement:
- 不通过 Bonjour 做本地 multicast discovery
- 枚举网络上的全部 Bonjour service type

关键点:

  • entitlement 不是普通 Bonjour App 的默认要求。
  • 如果只是搜索自己声明过的服务类型,优先使用 Bonjour 和 NSBonjourServices
  • 如果业务依赖 legacy hardware 的自定义多播协议,需要把 entitlement 申请纳入 iOS 14 适配计划。

4. 在用户动作之后再触发浏览

08:42)补齐 Info.plist 后,演示 App 一启动就开始 Bonjour browsing,系统立刻弹出权限提示。Apple 随后展示了更好的版本:启动时不浏览网络,等用户点 “Search for games” 再触发搜索。

较差体验:
App launch -> start Bonjour browsing -> system prompt appears immediately

较好体验:
App launch -> wait
User taps "Search for games" -> start Bonjour browsing -> system prompt explains this action

关键点:

  • 权限提示应该贴近用户刚刚发起的动作。
  • 本地网络用途说明要写出被启用的功能,例如发现附近玩家。
  • 如果 App 在启动时就浏览网络,用户很容易把权限请求看成无上下文的打扰。

5. 处理权限等待期间的 API 行为

10:32)本地网络权限会改变一些 API 的表现。Bonjour 结果是异步返回的,等待权限时看起来可能像附近没有设备。NWConnection 会留在 waiting 状态。使用本地网络的 URLSession task 应设置 waitsForConnectivity,socket 代码要处理系统调用错误。

let configuration = URLSessionConfiguration.default
configuration.waitsForConnectivity = true

let session = URLSession(configuration: configuration)

关键点:

  • waitsForConnectivity 是逐字稿中明确点名的属性,用于让本地网络 task 在权限授予后继续完成。
  • NWConnection 的 waiting 状态不一定代表服务器不可达,可能只是本地网络权限尚未授予。
  • 直接使用 sockets 时,不能假设本地网络总是可达,要把系统调用错误纳入正常路径。

核心启发

1. 附近玩家搜索入口

做什么:把附近对战、同屏协作、局域网房间列表放到一个明确的 “搜索附近设备” 按钮后面。

为什么值得做:session 演示说明,等用户主动开始搜索再触发 Bonjour browsing,权限弹窗更容易被理解。

怎么开始:先在 Info.plist 写 NSLocalNetworkUsageDescriptionNSBonjourServices,再把 Bonjour browser 的启动时机从 App launch 移到用户动作回调里。

2. 智能家居或相机配对流程

做什么:在设备配对页解释 App 将查找同一 Wi-Fi 下的相机、灯、音箱或控制器,然后再启动发现流程。

为什么值得做:Apple 明确把本地网络设备控制列为敏感场景,用户需要知道 App 为什么能看到附近设备。

怎么开始:列出真实使用的 Bonjour service type,给每个配对入口写清楚用途说明,并在 NoAuth 或空设备列表时引导用户检查本地网络权限。

3. 旧硬件的局域网协议审计

做什么:给使用 multicast、broadcast 或自定义发现协议的硬件 App 做一次 iOS 14 兼容清单。

为什么值得做:session 说明,绕开 Bonjour 的本地 multicast discovery 可能需要额外 entitlement。

怎么开始:先把能迁移到 Bonjour 的发现流程迁移到已声明 service type;确实需要枚举或自定义多播时,再准备 developer portal 的 entitlement 申请。

4. 本地网络连接的等待态 UI

做什么:在连接本地服务器、打印机或媒体设备时,把 “正在等待权限或网络连接” 做成正常状态,而不是直接显示失败。

为什么值得做:逐字稿提到,Bonjour 可能暂时没有结果,NWConnection 可能处于 waiting,URLSession 可以等待 connectivity。

怎么开始:为本地网络请求设置 waitsForConnectivity,把 NWConnection 的 waiting 状态接入 UI,并为 socket 错误提供用户可理解的恢复路径。

关联 Session

评论

GitHub Issues · utterances