Highlight
tvOS 15 通过 AuthenticationServices 提供系统登录视图,让用户用 iPhone 或 iPad 上的 iCloud Keychain、Face ID 或 Touch ID 完成 Apple TV App 的登录和购买授权。
核心内容
Apple TV 上的登录一直很麻烦。
媒体 App 往往要求用户输入邮箱和密码。用户为了安全,会使用很长、很随机的密码。这个密码放在电视遥控器上输入,体验很差。用户还没有看到内容,就先卡在登录页。
tvOS 15 的做法,是把登录流程拆给 Apple TV 和 iPhone 或 iPad 协同完成。用户在 Apple TV App 里点登录,拿起 iPhone 后会看到来自 Apple TV 的通知。点开通知,iPhone 会推荐 iCloud Keychain 里的凭据,并用 Face ID 或 Touch ID 确认。确认后,凭据回到 Apple TV,App 继续完成自己的服务端登录。
这套流程使用系统登录视图。它统一了 tvOS 上的登录入口,也告诉用户可以用 iPhone 或 iPad 继续操作。对 App 来说,核心代码仍然是 AuthenticationServices 框架里的 ASAuthorizationController。
登录页还可以保留其他入口。比如手动登录、使用电视服务提供商账号、恢复内购。开发者通过 customAuthorizationMethods 告诉系统要显示哪些额外按钮。用户选择后,App 再进入对应的自定义流程。
详细内容
配置 Associated Domains
(02:22)这套体验先要求 App 和网站域名建立安全关联。Apple TV 和 iPhone 或 iPad 需要确认某个凭据属于你的服务,才会安全地推荐给用户。
逐字稿给出三个配置步骤:
1. 在域名托管的 apple-app-site-association 文件中,
把 tvOS App 的 application identifier 写入 webcredentials key。
2. 在 Xcode 中为 tvOS App 添加 Associated Domains capability。
3. 在 Associated Domains 中加入带 webcredentials 前缀的域名。
关键点:
- 第 1 行:
apple-app-site-association文件放在你的域名下,用来声明哪些 App 可以使用这个域名的 Web 凭据。 - 第 2 行:Xcode 的 Associated Domains 能力让 App 参与系统级的域名关联。
- 第 3 行:
webcredentials前缀告诉系统,这个域名用于密码和登录凭据匹配。
这一步完成后,系统才能在 Apple TV 登录流程中,让 iPhone 或 iPad 安全地建议 iCloud Keychain 凭据。
请求密码凭据
(03:28)登录按钮被点击后,App 创建一个授权控制器,并传入密码请求。这里使用 ASAuthorizationPasswordProvider。
import AuthenticationServices
final class SignInViewController: UIViewController, ASAuthorizationControllerDelegate {
func beginSignIn() {
let controller = ASAuthorizationController(authorizationRequests: [
ASAuthorizationPasswordProvider().createRequest()
])
controller.delegate = self
controller.performRequests()
}
}
关键点:
- 第 1 行:引入 AuthenticationServices(认证服务)框架,后面的授权控制器和密码凭据类型都来自这里。
- 第 3 行:视图控制器遵守
ASAuthorizationControllerDelegate,用于接收授权成功或失败回调。 - 第 5 行:创建
ASAuthorizationController,它负责启动系统登录视图和授权流程。 - 第 6 行:
ASAuthorizationPasswordProvider().createRequest()表示这次登录要请求保存的用户名和密码。 - 第 9 行:把当前对象设为代理,后续结果会回到这个对象。
- 第 10 行:
performRequests()启动登录请求。用户会在 iPhone 或 iPad 上选择并确认凭据。
逐字稿提到,同一个 authorizationRequests 数组可以放入多种请求。如果 App 支持 Sign in with Apple,也可以把 Apple ID 请求放进去,让用户在 iPhone 或 iPad 上选择要使用的凭据类型。
用凭据完成登录
(04:19)用户在 iPhone 或 iPad 上选中凭据后,系统会调用 didCompleteWithAuthorization。如果返回的是 ASPasswordCredential,App 可以读取用户名和密码,交给自己的登录逻辑。
import AuthenticationServices
extension SignInViewController {
func authorizationController(controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization) {
if let credential = authorization.credential as? ASPasswordCredential {
// Use the credential to sign in
}
}
}
关键点:
- 第 3 行:把授权回调放在
SignInViewController的扩展里,和启动代码分开。 - 第 4 行:
authorizationController(_:didCompleteWithAuthorization:)是授权成功时的代理方法。 - 第 6 行:把
authorization.credential转成ASPasswordCredential,确认这次拿到的是密码凭据。 - 第 7 行:这里接入 App 现有的登录流程。逐字稿说明,可以使用凭据上的
user和password属性完成登录。
这个回调不会替你完成服务端认证。它只把用户确认过的凭据交给 App。App 仍然要把用户名和密码发送到自己的认证服务,并处理会话、订阅状态或内容权限。
处理取消和失败
(04:43)登录可能失败。用户也可能主动取消。tvOS 15 的建议是把取消当作正常路径处理,让界面回到主登录入口;其他错误再提示用户重试。
import AuthenticationServices
extension SignInViewController {
func authorizationController(controller: ASAuthorizationController,
didCompleteWithError error: Error) {
if case ASAuthorizationError.canceled = error { return }
// Let the user know something went wrong
}
}
关键点:
- 第 4 行:
authorizationController(_:didCompleteWithError:)是授权失败时的代理方法。 - 第 6 行:检查错误是否为
ASAuthorizationError.canceled。如果用户取消,直接返回。 - 第 7 行:其他错误需要告知用户登录出错,并允许重新尝试。
这个分支很重要。取消表示用户退出了当前登录流程。App 应该回到主登录界面,不需要弹出错误提示。
添加自定义登录方式
(06:00)系统登录视图可以显示额外按钮。适合的场景包括手动登录、恢复购买、使用电视服务提供商账号。
import AuthenticationServices
final class SignInViewController: UIViewController, ASAuthorizationControllerDelegate {
func beginSignIn() {
let controller = ASAuthorizationController(authorizationRequests: [
ASAuthorizationPasswordProvider().createRequest()
])
controller.customAuthorizationMethods = [
// Sign in Manually
.other,
// Restore Purchase
.restorePurchase
]
controller.delegate = self
controller.performRequests()
}
}
关键点:
- 第 5 行:仍然先创建
ASAuthorizationController,主流程是请求密码凭据。 - 第 9 行:设置
customAuthorizationMethods,告诉系统登录视图要显示哪些额外操作。 - 第 11 行:
.other可用于手动登录,也可以跳到你自己的登录方式选择界面。 - 第 13 行:
.restorePurchase用于让用户通过恢复内购完成登录或解锁。 - 第 16 行:设置代理,准备接收密码登录结果和自定义方式选择结果。
- 第 17 行:启动请求,系统登录视图会同时展示 iPhone/iPad 登录和自定义按钮。
逐字稿还提到 .videoSubscriberAccount。如果 App 支持使用电视服务提供商账号登录,应该使用这个值。
当用户点了自定义按钮,系统会调用代理里的 didCompleteWithCustomMethod。App 要检查传入的值,再启动对应流程。
import AuthenticationServices
extension SignInViewController {
func authorizationController(controller: ASAuthorizationController,
didCompleteWithCustomMethod method: ASAuthorizationController.CustomAuthorizationMethod) {
switch method {
case .other:
// Start your manual sign-in flow
break
case .restorePurchase:
// Start your restore purchase flow
break
default:
break
}
}
}
关键点:
- 第 4 行:
didCompleteWithCustomMethod在用户选择自定义登录方式时触发。 - 第 6 行:通过
switch判断用户选择了哪一种方式。 - 第 7 行:
.other对应手动登录或 App 自己的登录选择界面。 - 第 10 行:
.restorePurchase对应恢复购买流程。 - 第 13 行:默认分支处理当前没有接入的自定义方式。
设计一个更短的登录入口
(06:36)Apple 给出的 tvOS 登录最佳实践,是从一个清晰的「Sign In」按钮开始,然后让系统视图提供有限的选项。
@IBAction func signInButtonPressed(_ sender: Any) {
beginSignIn()
}
关键点:
- 第 1 行:登录按钮只负责响应用户动作,不在按钮事件里堆叠多个登录分支。
- 第 2 行:进入统一的
beginSignIn(),由ASAuthorizationController展示系统登录视图。
这样做的收益很直接:用户不用先判断自己该选哪种登录方式。默认路径是用 iPhone 或 iPad 完成登录。额外路径放到系统视图中,数量保持克制。
核心启发
-
做什么:给视频 App 增加「用 iPhone 登录」入口。 为什么值得做:tvOS 15 的系统登录视图可以直接引导用户在 iPhone 或 iPad 上选取 iCloud Keychain 凭据,减少遥控器输入。 怎么开始:配置
webcredentialsAssociated Domains,在登录按钮中创建ASAuthorizationController,传入ASAuthorizationPasswordProvider().createRequest()。 -
做什么:把恢复订阅放进登录视图。 为什么值得做:很多媒体 App 的「登录」和「恢复购买」都通向内容权限校验。
customAuthorizationMethods可以把恢复购买作为系统登录视图中的明确选项。 怎么开始:设置controller.customAuthorizationMethods = [.restorePurchase],在didCompleteWithCustomMethod中启动 StoreKit 的恢复购买流程。 -
做什么:为家庭共享电视准备手动登录兜底。 为什么值得做:有些用户没有在 iCloud Keychain 中保存凭据,或者想使用另一个账号。
.other可以从系统视图跳到 App 自己的手动登录界面。 怎么开始:把.other加入customAuthorizationMethods,在回调中打开用户名和密码输入页面。 -
做什么:把电视服务提供商账号接入同一个登录入口。 为什么值得做:逐字稿说明,支持 TV provider account 的 App 应该使用
.videoSubscriberAccount。用户不用在首屏面对多个并列按钮。 怎么开始:在自定义方式中加入.videoSubscriberAccount,用户选择后进入现有的电视服务提供商授权流程。 -
做什么:把登录取消作为正常状态写入 UI 流程。 为什么值得做:用户取消授权时,系统会返回
ASAuthorizationError.canceled。这个状态适合回到主登录页。 怎么开始:在didCompleteWithError中先判断ASAuthorizationError.canceled,取消时回到主登录页,其他错误再展示重试提示。
关联 Session
- Move beyond passwords — 解释密码带来的安全问题,以及 Apple 推动无密码登录的方向。
- Secure login with iCloud Keychain verification codes — 介绍 iCloud Keychain 验证码自动填充,适合改进二次验证体验。
- Use the camera for keyboard input in your app — 展示如何用相机和 Live Text 降低输入成本,和 tvOS 登录的目标相同。
- Deliver a great playback experience on tvOS — 面向媒体 App 的 tvOS 播放体验更新,适合和登录后内容体验一起规划。
评论
GitHub Issues · utterances