我知道有其他类似的问题,但它们都是关于 Auth.auth().signIn
和 signUp
分别,在函数中存在一个完成处理参数。
我试图在匿名函数中加入一个符号,以使我的 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
}
}
谁能告诉我如何解决这个错误?
你粘贴的代码片段来自一个过时的教程。从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匿名认证)。第三部分 (用苹果登录)