关于firebase:void函数中意外的非void返回值 – Swift

Unexpected non-void return value in void function - Swift

不让我返回用户名值,因为它在闭包中。有人可以向我解释如何使用 @escaping 和 void 闭包

错误:void 函数中出现意外的非 void 返回值

1
2
3
4
5
6
7
8
9
10
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
    }
}

与其返回字符串值,不如将其设为闭包,因为 database.getDocument 在闭包中也会返回错误。

所以让你的函数成为一个闭包。

像这样。

1
2
3
4
5
6
7
8
9
10
11
    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)
        }
    }
}


getDocument 是异步方法,回调闭包没有返回,所以你不能从它返回,相反你必须在某处应用结果,例如。在属性

所以解决方法可以如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
           }
    }
}