简化 tvOS App 的登录体验
Simplify sign in for your tvOS apps
2021年6月8日
一句话判断
tvOS 上输入密码是一种酷刑——支持 iPhone 自动填充登录是你的 App 用户体验的底线要求,不是加分项。
这场 Session 讲了什么
这个 Session 聚焦在 tvOS 上最让人头疼的问题:登录。Apple TV 没有触摸屏,遥控器打字体验很差,任何需要用户输入用户名和密码的步骤都会大幅降低转化率。iOS 15 和 tvOS 15 提供了多种方案来简化这个过程。
Session 介绍了三种主要的简化方案:一是「通过 iPhone 认证」——用户在 Apple TV 上点击登录后,iPhone 上会弹出通知,直接用 Face ID/Touch ID 完成认证,不需要在 TV 上输入任何东西。这是基于 ASAuthorizationController 的 Sign in with Apple 能力的扩展。二是 iCloud Keychain 密码自动填充——用户在 iOS 上保存的密码可以通过 iCloud 同步到 tvOS,在输入框中自动提示。三是 VPN App 的快速配置——tvOS 15 新增了 NETunnelProviderManager 的配置推送能力,用户可以在 iPhone 上配置好 VPN 然后一键推送到 Apple TV。
对于大多数 tvOS 开发者来说,Session 的核心建议很明确:如果你的 App 需要登录,必须支持至少一种免输入方案。
值得深挖的点
ASAuthorizationController 在 tvOS 上的跨设备流程。 tvOS 上的 Sign in with Apple 有一个特殊的「跨设备」模式:当你在 Apple TV 上发起登录请求时,系统会通过 iCloud 通知用户的 iPhone 或 iPad,用户在移动设备上完成 Face ID 验证后,认证结果自动回传给 Apple TV。整个过程用户不需要在 TV 上做任何操作。实现方式是使用 ASAuthorizationController 的 performRequests() 方法,tvOS 上会自动触发跨设备流程。你的 App 需要处理 authorizationController(controller:didCompleteWithAuthorization:) 回调来获取 credential。
iCloud Keychain 在 tvOS 上的自动填充机制。 tvOS 15 支持在 UITextField 中自动填充 iCloud Keychain 里保存的密码。当你的 tvOS App 的输入框获得焦点时,如果 Keychain 中有匹配当前域名的账号密码,系统会在输入框下方显示提示。用户只需要用遥控器选择即可完成填充,不需要用遥控器逐字输入。前提是你在 App 的 Associated Domains 中配置了正确的域名,并在服务端部署了 apple-app-site-association 文件。
代码片段
import AuthenticationServices
// tvOS 上使用 Sign in with Apple 的跨设备认证
class SignInViewController: UIViewController {
func startSignIn() {
let request = ASAuthorizationAppleIDProvider().createRequest()
request.requestedScopes = [.fullName, .email]
let controller = ASAuthorizationController(authorizationProvider: ASAuthorizationAppleIDProvider(),
requests: [request])
controller.delegate = self
controller.performRequests()
// tvOS 上会自动在用户的 iPhone/iPad 上弹出认证通知
}
}
extension SignInViewController: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization) {
// 获取用户 credential,登录成功
let credential = authorization.credential as? ASAuthorizationAppleIDCredential
let userId = credential?.user
let identityToken = credential?.identityToken
}
}
// 在 tvOS 的 UITextField 中启用密码自动填充
let usernameField = UITextField()
usernameField.textContentType = .username
let passwordField = UITextField()
passwordField.textContentType = .password
passwordField.isSecureTextEntry = true
// Keychain 中的密码会自动出现在输入建议中
// 检查用户是否已经通过 Sign in with Apple 登录过
func checkExistingSignIn() {
let provider = ASAuthorizationAppleIDProvider()
provider.getCredentialState(forUserID: storedUserId) { state, error in
switch state {
case .authorized:
// 用户已登录,直接进入 App
break
case .revoked, .notFound:
// 需要重新登录
break
default:
break
}
}
}
最佳实践
- tvOS App 的登录流程必须支持至少一种免输入方案(Sign in with Apple 或 iCloud Keychain),否则用户流失率会非常高
- 如果你同时提供 Sign in with Apple 和传统用户名/密码登录,把 Sign in with Apple 放在登录界面的最显眼位置
- 测试跨设备认证时,确保 Apple TV 和 iPhone 登录了同一个 iCloud 账号,且两台设备都连接到了互联网
- 对于付费内容 App(视频、音乐),考虑在用户首次打开时就引导登录,而不是等到用户想看内容时才弹出
还有什么值得关注
- tvOS 15 还支持通过 iPhone 配置 Apple TV 的网络设置(包括 VPN),通过
NETunnelProviderManager实现 UISimpleTextInput在 tvOS 上可以接收来自 iPhone 的键盘输入,这是另一个减少 TV 端输入的方案- 用户可以在「设置 > 用户和账户」中管理所有 tvOS App 的登录状态,App 应该正确响应 credential state 的变化