不让我返回用户名的值,因为它在一个闭包中。谁能给我解释一下如何使用@escaping和void闭合。
错误:在void函数中出现意外的非void返回值。在void函数中,意外的非void返回值。
func grabUsername () -> String {
let uid = Auth.auth().currentUser?.uid
let database = Firestore.firestore().collection("Users").document(uid!)
database.getDocument { (docSnapshot, error) in
guard let docSnapshot = docSnapshot, docSnapshot.exists else {return}
let mydata = docSnapshot.data()
let username = mydata!["Username"] as? String ?? ""
return username
}
}
该 getDocument
是异步方法,它的回调闭包没有返回,所以你不能从它那里返回,而是要把结果应用到某个地方,例如在属性中。
因此,解决方案可以如下
var username: String = ""
// ... other your code
func grabUsername () { // << async, no immediate return
let uid = Auth.auth().currentUser?.uid
let database = Firestore.firestore().collection("Users").document(uid!)
database.getDocument { (docSnapshot, error) in
guard let docSnapshot = docSnapshot, docSnapshot.exists else {return}
let mydata = docSnapshot.data()
let username = mydata!["Username"] as? String ?? ""
DispatchQueue.main.async {
self.username = username // << store result
}
}
}
与其返回一个String值,不如让它成为一个闭包,这将是一个更好的方法,如 database.getDocument
也是在一个闭包中返回一个错误。
所以把你的函数做成一个闭包。
像这样。
func grabUsername (completion: @escaping (Error?, String?) -> Void) {
let uid = Auth.auth().currentUser?.uid
let database = Firestore.firestore().collection("Users").document(uid!)
database.getDocument { (docSnapshot, error) in
if error != nil { completion(error.localizedDescription!, nil) } else { guard let docSnapshot = docSnapshot, docSnapshot.exists else {return}
let mydata = docSnapshot.data()
let username = mydata!["Username"] as? String ?? ""
completion(nil, username)
}
}
}