Chris Comas
Chris Comas

Reputation: 216

Unexpected non-void return value in void function - Swift

Not letting me return the username value because its in a closure. May someone please explain to me how to use the @escaping and void closure

Error: Unexpected non-void return value in void function

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
    }
}

Upvotes: 3

Views: 3929

Answers (2)

Tabish Sohail
Tabish Sohail

Reputation: 1044

Instead of returning a String value, making it a closure will be a better approach, as database.getDocument is returning an error also in a closure.

So make your function as a closure.

like this.

    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)
        }
    }
}

Upvotes: 1

Asperi
Asperi

Reputation: 258117

The getDocument is asynchronous method with callback closure having no return, so you cannot return from it, instead you have to apply results somewhere, eg. in property

So the solution can be as follow

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
           }
    }
}

Upvotes: 2

Related Questions