WWDC Quick Look 💓 By SwiftGGTeam
What’s new in location authorization

What’s new in location authorization

观看原视频

Highlight

Core Location 的授权一直是个复杂的话题。用户可能授予了”使用期间”但只是”近似位置”,你的某个功能突然需要”精确位置”,就得调用 requestTemporaryFullAccuracy。如果用户之前选了”允许一次”然后切到别的 App,授权就丢了,你又得重新请求。不同授权状态的排列组合让代码变得很脆弱。


核心内容

用 CLLocationManager 管理位置授权,代码很容易变得脆弱。用户选了”允许一次”,切到别的 App 再回来,授权就丢了,你又得重新调 requestWhenInUseAuthorization。用户给了近似位置,你的导航功能需要精确位置,又要调 requestTemporaryFullAccuracy(withPurposeKey:),但临时授权会过期。整个过程是过程式的:你得自己判断当前状态、自己决定下一步调哪个方法,稍有遗漏就会卡在某个分支上。

iOS 18 引入的 CLServiceSession 把这个模型从”过程式”翻转为”声明式”。你创建一个 session,告诉系统你需要什么授权等级(比如 .whenInUse),系统负责在合适的时机向用户弹出请求。如果某个功能需要精确位置,你再创建一个带 fullAccuracyPurposeKey 的 session——是叠加,不是替换。每个功能模块独立声明自己的授权需求,Core Location 统一处理。另外,当你迭代 CLLocationUpdate.liveUpdatesCLMonitor.events 这些 AsyncSequence 时,系统会自动认为你有一个 .whenInUse 的隐式 session,很多场景下只需要删掉旧的手动授权代码就够了。

详细内容

CLServiceSession 的基本用法01:07

以前要获取位置授权,需要写一大段 CLLocationManager + delegate 代码。现在用 CLServiceSession 只需几行:

// CLServiceSession in action

Task {
    let session = CLServiceSession(authorization: .whenInUse)

    for try await update in CLLocationUpdate.liveUpdates {
        // Process update.location or update.authorizationDenied
    }
}

关键点:

  • CLServiceSession(authorization: .whenInUse) 声明你的授权目标是”使用期间”,系统会自动在合适时机请求授权
  • session 的生命周期由你持有它的时长决定:持有期间系统知道你的目标,释放后系统不再为该目标维护授权
  • CLLocationUpdate.liveUpdates 的迭代本身也会创建隐式的 .whenInUse session(07:15

叠加 fullAccuracy 的 session04:08

当用户启动导航功能时,需要精确位置。做法是叠加一个带 fullAccuracyPurposeKey 的 session,而不是替换原来的:

// 基础 session:只需要近似位置
let baseSession = CLServiceSession(authorization: .whenInUse)

// 导航功能需要精确位置,叠加一个 session
let navSession = CLServiceSession(
    authorization: .whenInUse,
    fullAccuracyPurposeKey: "Nav"
)

关键点:

  • fullAccuracyPurposeKey: "Nav" 对应 Info.plist 中的本地化字符串,向用户解释为什么需要精确位置
  • 叠加(layering)而不是替换:基础 session 保持不变,新 session 额外声明精确位置需求
  • 每个功能模块独立创建和释放自己的 session,不需要模块间协调

隐式 Service Session07:34

迭代 liveUpdates 本身就隐含了 .whenInUse 的授权目标,可以省去显式创建 session:

Task {
    for try await update in CLLocationUpdate.liveUpdates {
        // Process update.location or update.authorizationDenied
    }
}

关键点:

  • 隐式 session 默认启用,迭代 liveUpdatesmonitor.events 时自动生效
  • 如果不需要隐式行为,在 Info.plist 中设置 NSLocationRequireExplicitServiceSession 即可关闭
  • 隐式 session 不包含 .alwaysfullAccuracy 需求,这些必须显式声明

Diagnostic Properties13:37

CLServiceSession 暴露一个 diagnostics AsyncSequence,让你实时了解授权状态:

// Following the progress of location authorization with CLServiceSession
Task {
    let mySession = CLServiceSession(authorization:.whenInUse)

    for try await diagnostic in mySession.diagnostics {
        if (!diagnostic.authorizationRequestInProgress) {
            reactToChanges(authorized:!diagnostic.authorizationDenied)
        }
    }
}

关键点:

  • diagnostic.authorizationRequestInProgress 为 false 时,表示用户已做出选择(或之前已有授权)
  • diagnostic.authorizationDenied 表示授权被拒绝
  • diagnostic.authorizationDeniedGlobally 表示系统级位置服务被关闭,可以据此给出不同的引导
  • diagnostic.insufficientlyInUse 表示当前状态不足以让系统弹出授权请求
  • CLLocationUpdate 和 CLMonitor.Event 也新增了 Diagnostic Properties:.accuracyLimited(近似位置每 15-20 分钟才更新一次)、.locationUnavailable(Core Location 暂时无法确定位置)

核心启发

  • 做什么:用 CLServiceSession 替换所有 CLLocationManager 的手动授权请求代码。为什么值得做:声明式模型消除了”当前在哪个状态、下一步该调什么方法”的判断逻辑,系统自动处理授权恢复(比如 App 被 suspend 后重新回到前台)。怎么开始:找到项目中所有 requestWhenInUseAuthorization()requestTemporaryFullAccuracy(withPurposeKey:) 调用,替换为对应功能模块中创建的 CLServiceSession。

  • 做什么:为需要精确位置的功能独立创建带 fullAccuracyPurposeKey 的叠加 session。为什么值得做:用户可能愿意给近似位置但不想给精确位置,叠加 session 让每个功能的授权需求自包含,不会因为一个功能的需求影响其他功能。怎么开始:列出 App 中所有需要精确位置的功能点,每个功能在激活时创建 CLServiceSession(authorization: .whenInUse, fullAccuracyPurposeKey: "YourKey"),功能结束时释放。

  • 做什么:用 Diagnostic Properties 替换项目中的超时和猜测逻辑。为什么值得做:以前无法区分”等待位置更新中”和”授权被拒绝”,只能设超时;现在可以直接检查 .authorizationDenied.accuracyLimited 等属性,给出准确的 UI 反馈。怎么开始:在迭代 liveUpdatesdiagnostics 的循环中,检查每个 update/event 的 Diagnostic Properties,根据不同属性值展示对应的 UI 状态(比如”位置精度受限,导航可能不准确”)。

  • 做什么:确保 App 启动时重建之前的 session。为什么值得做:Core Location 在 App 被 terminate 后只保留 session 状态几秒钟,App 重新启动后必须尽快重新创建 session,否则后台位置更新会中断。怎么开始:在 App 的启动逻辑中,根据持久化的功能状态(比如”正在记录运动轨迹”)立即重建对应的 CLServiceSession 或恢复 liveUpdates 的迭代。

关联 Session

评论

GitHub Issues · utterances