Flutter 接入 Apple 账号登录教程

引言

2019 年底,苹果发布了 iOS 13,并增加了一个新要求:任何使用第三方登录方法的应用(如 Facebook、Google、Twitter 等)在提交到 App Store 时必须也支持 Sign in with Apple。本文将详细介绍如何在 Flutter 中实现这一功能,包括项目配置、iOS 部分的实现,以及 Flutter 代码的编写。

关于 Sign in with Apple

什么是 Sign in with Apple? Sign in with Apple 是一种授权方式,用户点击带有 Apple 标志的按钮,输入 Apple 账号密码或使用生物识别方式(TouchID、FaceID)进行登录。这种方法简单易用,但作为开发者,你需要了解一些特别之处。

何时需要 Sign in with Apple? 如果你的 iOS 应用使用了第三方认证方法,必须实现 Sign in with Apple。在 Android 版本中可以选择不实现,因为这仅适用于 App Store。

注意事项:

  1. 用户可以选择更改姓名。
  2. 用户可以隐藏真实邮箱,提供一个由 Apple 生成的邮箱。
  3. 用户可以随时停止邮件转发。

值得注意的是,Apple 只会在用户首次登录时提供这些信息。

实现步骤
配置
  1. 在 iPhone 或模拟器上运行你的应用,然后打开 Xcode 项目。你可以通过终端输入 open ios/Runner.xcworkspace 打开项目。
  2. 打开项目的主配置文件,选择 “Signing & Capabilities” 标签,指定你的 Apple 开发团队。
  3. 点击 “+ Capability” 按钮,搜索 “Sign in with Apple”,双击选中。
添加按钮

关于 Sign in with Apple 按钮 要让用户通过 Sign in with Apple 认证,必须在应用中添加一个合适的按钮。该按钮应该包含 Apple 标志和 “Sign in with Apple” 标题,并且使用 Apple 提供的设计以避免应用被拒。

有三种允许的按钮样式可供选择:

  • 黑色标志,白色背景
  • 白色标志,黑色背景
  • 黑色标志,白色背景,带黑色边框

按钮的高度和圆角可以根据你的需求进行调整。确保按钮在登录页面显著可见,最好位于所有其他登录按钮之上。

实现

在 Flutter 中添加 Sign in with Apple 按钮有两种方法:

  1. 重新绘制按钮
  2. 使用 iOS 视图(推荐)

使用 iOS 视图的步骤:

在你的 Dart 代码中,找到要放置 Sign in with Apple 按钮的 build() 方法,并添加以下代码:

代码语言:javascript代码运行次数:0运行复制
SizedBox(
  width: MediaQuery.of(context).size.width * 0.8,
  height: 60.0,
  child: UiKitView(viewType: 'AppleSignIn'),
),

然后,进入 iOS 代码,假设使用 Swift 语言,打开 AppDelegate.swift 文件,并在文件顶部导入 AuthenticationServices 库:

代码语言:javascript代码运行次数:0运行复制
import AuthenticationServices

接下来,添加以下类以实现按钮的显示:

代码语言:javascript代码运行次数:0运行复制
class AppleSignInView: NSObject, FlutterPlatformView {
    let frame: CGRect
    let viewId: Int64
    let args: Any?
    let window: UIWindow
    
    init(_ frame: CGRect, viewId: Int64, args: Any?, window: UIWindow) {
        self.frame = frame
        self.viewId = viewId
        self.args = args
        self.window = window
    }
    
    func view() -> UIView {
        if #available(iOS 13.0, *) {
            let button = ASAuthorizationAppleIDButton(frame: frame)
            return button
        } else {
            return UIView()
        }
    }
}

然后添加另一个类:

代码语言:javascript代码运行次数:0运行复制
class AppleSignInViewFactory: NSObject, FlutterPlatformViewFactory {
    let window: UIWindow
    
    init(window: UIWindow) {
        self.window = window
    }
    
    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        return AppleSignInView(frame, viewId: viewId, args: args, window: window)
    }
}

application(_:launchOptions:) 方法中添加以下代码:

代码语言:javascript代码运行次数:0运行复制
let viewFactory = AppleSignInViewFactory(window: window)
registrar(forPlugin: "AnyString").register(viewFactory, withId: "AppleSignIn")

最后,在 Info.plist 文件中添加以下内容以允许 Flutter 显示 iOS 视图:

代码语言:javascript代码运行次数:0运行复制
<key>io.flutter.embedded_views_preview</key>
<true/>
添加逻辑

现在,我们已经有了按钮,接下来处理授权流程。在 AppleSignInView 类中,实现两个接口:

  1. ASAuthorizationControllerPresentationContextProviding
  2. ASAuthorizationControllerDelegate

首先是第一个扩展:

代码语言:javascript代码运行次数:0运行复制
@available(iOS 13, *)
extension AppleSignInView: ASAuthorizationControllerPresentationContextProviding {
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return window
    }
}

接下来是第二个扩展:

代码语言:javascript代码运行次数:0运行复制
@available(iOS 13, *)
extension AppleSignInView: ASAuthorizationControllerDelegate {
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        switch authorization.credential {
        case let appleIdCredential as ASAuthorizationAppleIDCredential:
            // 获取用户数据,必要时创建账户并通过通道发送给 Flutter
            break
        default:
            break
        }
    }
}

view() 方法中注册按钮的点击事件:

代码语言:javascript代码运行次数:0运行复制
button.addTarget(self, action: #selector(onSignInWithAppleTap), for: .touchUpInside)

并添加 onSignInWithAppleTap 方法:

代码语言:javascript代码运行次数:0运行复制
@objc func onSignInWithAppleTap() {
    if #available(iOS 13.0, *) {
        let appleIdProvider = ASAuthorizationAppleIDProvider()
        let request = appleIdProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
        
        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    }
}
总结

以上就是在 Flutter 应用中实现 Sign in with Apple 的所有步骤。希望本教程能帮助你顺利完成集成!如果有任何疑问,欢迎在评论区交流。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-09-30,如有侵权请联系 cloudcommunity@tencent 删除flutterapple登录教程配置