Support multiple users in your tvOS app
System & Services 进阶 17m

在 tvOS 应用中支持多用户

Support multiple users in your tvOS app

2020年6月24日

在 Apple 官方观看视频

一句话判断

tvOS 14 终于给 Apple TV 加上了系统级多用户支持——你的 app 现在可以感知当前登录用户并自动切换数据,不再是「全家人共享一个账号」的尴尬局面了。

这场 Session 讲了什么

Apple TV 一直是客厅共享设备,但长久以来 tvOS 没有真正的多用户 API。tvOS 14 修复了这个问题,引入了 UserProfile 和相关的用户切换通知机制。

Session 详细讲解了如何在 tvOS app 中集成多用户支持:检测当前活跃用户、监听用户切换事件、根据不同用户加载个性化内容。重点介绍了 tvOS 14 新增的 Profile 框架,它提供了系统级的用户身份管理。

对于视频类、游戏类 app 来说,这意味着每个家庭成员可以有独立的观看历史、推荐列表和游戏存档,不再需要手动切换。tvOS 系统层面会在控制中心显示当前用户,app 层面通过 API 同步感知。

值得深挖的点

用户切换的生命周期管理

当用户在系统设置中切换用户时,tvOS 会发送 GCControllerPlayerIndexDidChange 通知(针对游戏)以及通过 UserProfile API 反馈变化。你的 app 需要在收到通知后做三件事:保存当前用户状态、清理缓存、加载新用户数据。Session 特别强调,切换过程中要确保不出现数据混淆——比如上一个用户的播放列表不能泄漏给新用户。

与 TVUserManager 的配合

TVUserManager 是 tvOS 14 新引入的核心类,它管理着当前活跃用户的 identifier 和显示名称。你可以用它来判断「当前是谁在用 Apple TV」,并在用户列表变更时收到回调。需要注意的是,用户可能选择匿名模式,此时 identifier 为空,app 需要处理这种边界情况。

代码片段

import TVServices

// 获取当前用户信息
class UserProfileManager {
    let userManager = TVUserManager()
    
    func setupUserTracking() {
        // 监听用户切换
        userManager.userDidChangeHandler = { [weak self] userIdentifier in
            guard let identifier = userIdentifier else {
                // 匿名模式,显示通用内容
                self?.loadAnonymousContent()
                return
            }
            // 加载该用户的个性化数据
            self?.loadContent(for: identifier)
        }
    }
    
    private func loadContent(for userID: String) {
        // 根据 userID 从本地或服务端加载个性化数据
        let userDefaults = UserDefaults(suiteName: "group.com.app.user.\(userID)")
        let lastPlayed = userDefaults?.string(forKey: "lastPlayed")
        // 恢复用户的上次播放进度
    }
    
    private func loadAnonymousContent() {
        // 匿名模式下加载通用推荐内容
    }
}
// 在 tvOS 中获取所有可用用户列表
func fetchAvailableProfiles() {
    let profileStore = UserProfileStore.shared
    
    profileStore.fetchProfiles { profiles, error in
        guard let profiles = profiles else { return }
        
        for profile in profiles {
            print("用户: \(profile.displayName)")
            print("标识: \(profile.identifier)")
        }
    }
}

最佳实践

  1. 数据隔离要彻底。每个用户的数据(播放历史、收藏、设置)必须独立存储,使用 UserDefaults(suiteName:) 或 Keychain 的 kSecAttrAccessGroup 配合用户 identifier 做隔离。不要把所有用户数据塞同一个 plist 里然后靠前缀区分——迟早会出 bug。
  2. 用户切换要无感。切换过程不要弹确认框,不要让用户等待超过 0.5 秒。提前预加载常用用户数据,切换时用交叉淡入淡出的动画过渡。
  3. 首次启动引导要简洁。如果 app 检测到系统有多个用户但 app 内没有对应数据,不要一个一个问,直接用当前系统用户创建默认配置,后续在设置里允许关联其他用户。

还有什么值得关注

  • tvOS 14 的控制中心可以直接切换用户,不需要进入设置 app,大大降低了多用户切换的摩擦。
  • Apple TV 的多用户支持与 HomePod 的多用户识别是同一套身份体系,如果你的 app 同时在两个平台运行,可以共享用户数据。
  • 游戏类 app 可以配合 Game Controller 框架的多玩家支持,让不同手柄绑定不同用户。
WWDC 2020