无法转换`AuthResultCallback`类型的值?

问题描述 投票:0回答:1

我知道有其他类似的问题,但它们都是关于 Auth.auth().signInsignUp 分别,在函数中存在一个完成处理参数。

我试图在匿名函数中加入一个符号,以使我的 SessionStore 类,这样我的应用就能观察到用户的状态,即他是登录(匿名或其他)还是注销,并相应地显示相关视图。

然而,当我试图将匿名登录添加到我的 SessionStore 类,我得到以下错误。

Cannot convert value of type 'AuthResultCallback' (aka '(Optional<User>, Optional<Error>) -> ()') to expected argument type 'AuthDataResultCallback?' (aka 'Optional<(Optional<AuthDataResult>, Optional<Error>) -> ()>')

我的代码如下

class SessionStore: ObservableObject {
    var didChange = PassthroughSubject<SessionStore, Never>()

    @Published var session: User? {didSet {self.didChange.send(self)}}
    var handle: AuthStateDidChangeListenerHandle?

     func listen() {
         handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
            if let user = user {
                self.session = User(uid: user.uid, email: user.email)
            } else {
                self.session = nil
            }
        })
    }

    func signUp(email: String, password: String, handler: @escaping AuthDataResultCallback) {
        Auth.auth().createUser(withEmail: email, password: password, completion: handler)
    }

    func signIn(email: String, password: String, handler: @escaping AuthDataResultCallback) {
        Auth.auth().signIn(withEmail: email, password: password, completion: handler)
    }

    func signOut() {
        do {
            try Auth.auth().signOut()
            self.session = nil
        } catch {
            print("Error signing user out")
        }
    }

    func signUpAnonymously(handler: @escaping AuthResultCallback) {

        Auth.auth().signInAnonymously(completion: handler) // **ERROR APPEARS HERE**

    }

    func unbind() {
        if let handle = handle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
    }

    deinit {
        unbind()
    }

}

struct User {

    var uid: String
    var email: String?

    init(uid: String, email: String?) {
        self.uid = uid
        self.email = email
    }
}

谁能告诉我如何解决这个错误?

swift firebase firebase-authentication swiftui handler
1个回答
0
投票

你粘贴的代码片段来自一个过时的教程。从Xcode 11 beta 5开始,您不再需要使用 PassthroughSubject 来发送财产变更的通知。Sarun的博客文章 有一个伟大而简洁的部分,我鼓励你阅读它。

还请注意,你不需要定义你自己的。User 类,因为这些属性已经定义在Firebase自己的 User 类型(通过实现 UserInfo 协议)。)

这里有一个片段,展示了如何实现你感兴趣的回调(见 registerStateListener).

class AuthenticationService: ObservableObject {

  @Published var user: User?

  private var handle: AuthStateDidChangeListenerHandle?

  init() {
    registerStateListener()
  }

  func signIn() {
    if Auth.auth().currentUser == nil {
      Auth.auth().signInAnonymously()
    }
  }

  func signOut() {
    do {
      try Auth.auth().signOut()
    }
    catch {
      print("Error when trying to sign out: \(error.localizedDescription)")
    }
  }

  func updateDisplayName(displayName: String, completionHandler: @escaping (Result<User, Error>) -> Void) {
    if let user = Auth.auth().currentUser {
      let changeRequest = user.createProfileChangeRequest()
      changeRequest.displayName = displayName
      changeRequest.commitChanges { error in
        if let error = error {
          completionHandler(.failure(error))
        }
        else {
          if let updatedUser = Auth.auth().currentUser {
            print("Successfully updated display name for user [\(user.uid)] to [\(updatedUser.displayName ?? "(empty)")]")
            // force update the local user to trigger the publisher
            self.user = updatedUser
            completionHandler(.success(updatedUser))
          }
        }
      }
    }
  }

  private func registerStateListener() {
    if let handle = handle {
      Auth.auth().removeStateDidChangeListener(handle)
    }
    self.handle = Auth.auth().addStateDidChangeListener { (auth, user) in
      print("Sign in state has changed.")
      self.user = user

      if let user = user {
        let anonymous = user.isAnonymous ? "anonymously " : ""
        print("User signed in \(anonymous)with user ID \(user.uid). Email: \(user.email ?? "(empty)"), display name: [\(user.displayName ?? "(empty)")]")
      }
      else {
        print("User signed out.")
        self.signIn()
      }
    }
  }

}

如果你对更多的背景感兴趣,请查看我的系列文章,关于用SwiftUI和Firebase构建一个待办事项应用。第一部分 使用SwiftUI构建UI)。第二部分 将数据存储在Firestore中,并使用Firebase匿名认证)。第三部分 (用苹果登录)

© www.soinside.com 2019 - 2024. All rights reserved.