Swift中能否在Delegate方法内使用Completion Handler?Google登录场景求助
解决方案:在单例LoginHelper中关联Google登录Delegate与Completion Handler
完全可以实现你的需求!核心思路就是在单例类里临时存储当前登录请求对应的Completion Handler,等Google登录的Delegate回调触发时,再调用这个handler并传递结果。下面是具体的实现步骤和代码示例:
1. 让LoginHelper遵循GIDSignInDelegate
首先确保你的单例类实现GIDSignInDelegate协议,这样才能接收Google登录的回调事件。
2. 临时存储Completion Handler
在单例类中添加一个可选闭包属性,用来暂存当前登录请求的completion handler。注意用完后要及时置空,避免内存泄漏或重复调用。
3. 在登录方法中配置Delegate并保存Handler
调用Google登录接口前,把当前单例设置为GIDSignIn的delegate,同时保存传入的completion handler。
4. 在Delegate方法中触发Completion Handler
当Google登录的回调方法(signIn(_:didSignInFor:withError:))被调用时,根据登录结果触发之前保存的handler,之后立即清空handler。
完整代码示例
import GoogleSignIn class LoginHelper: NSObject, GIDSignInDelegate { // 单例实现 static let shared = LoginHelper() private override init() { super.init() } // 暂存当前登录请求的completion handler private var loginCompletion: ((Bool) -> Void)? @objc func googleLoginPressed(viewController: UIViewController, isLoginSuccessfull: @escaping (Bool) -> ()) { // 保存传入的completion handler loginCompletion = isLoginSuccessfull // 配置Google登录的代理为当前单例 GIDSignIn.sharedInstance().delegate = self GIDSignIn.sharedInstance().presentingViewController = viewController // 发起Google登录请求 GIDSignIn.sharedInstance().signIn() } // MARK: - GIDSignInDelegate func signIn(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { // 切换到主线程执行completion(Google回调可能在后台线程触发) DispatchQueue.main.async { [weak self] in guard let self = self else { return } if let error = error { print("Google登录失败: \(error.localizedDescription)") self.loginCompletion?(false) } else { // 这里可以额外处理用户信息,比如获取token、用户昵称等 print("Google登录成功,用户名: \(user.profile?.name ?? "未知")") self.loginCompletion?(true) } // 调用后清空handler,防止重复触发 self.loginCompletion = nil } } // 可选:处理登出相关的回调 func signIn(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) { // 这里可以添加登出后的逻辑处理 } }
关键注意事项
- 内存安全:使用
[weak self]避免循环引用,因为单例是全局生命周期,闭包若强引用self可能导致内存泄漏。 - 主线程执行:Google登录的回调可能在后台线程触发,必须切换到主线程执行completion handler,确保后续UI操作(如页面跳转、提示弹窗)不会出错。
- 清空Handler:每次调用完completion handler后务必置空
loginCompletion,防止同一handler被重复调用(比如用户连续点击登录按钮的情况)。
这样就能完美实现把Google登录的Delegate回调通知到对应的Completion Handler了!
内容的提问来源于stack exchange,提问作者erdemgc
相关产品推荐
相关产品推荐

