Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

ios - Unexpected non-void return value in void function Swift3

I have a function that returns either a class object or nil. The function's purpose is to check if a Chat exists. The chat ID's are stored in MySQL. If the ID exists, I perform a Firebase reference to get a snapshot and then get the object. If the ID does not exist, I return nil:

func findChat(string: String) -> Chat? {

    var returnValue: (Chat?)
    let url = getChatsURL
    let Parameters = [ "title" : string ]

    Alamofire.request("(url)", method: .post, parameters: Parameters).validate().responseString { response in
            if let anyResponse = response.result.value {
                self.responseFromServer = anyResponse
            }

            if self.responseFromServer == "" {
              returnValue = nil
            } else {
                let ref = DatabaseReference.chats.reference()
                let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: (self.responseFromServer))
                query.observe(.childAdded, with: { snapshot in
                returnValue = Chat(dictionary: snapshot.value as! [String : Any])
            })
        }
        return returnValue
    }

}

However, at return returnValue I am getting

Unexpected non-void return value in void function.

Any thoughts of what I could be missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that you are trying to return a non-void value from inside a closure, which only returns from the closure, but since that closure expects a void return value, you receive the error.

You cannot return from an asynchronous function using the standard return ... syntax, you have to declare your function to accept a completion handler and return the value from the async network call inside the completion handler.

func findChat(string: String, completion: @escaping (Chat?)->()) {
    var returnValue: (Chat?)
    let url = getChatsURL
    let Parameters = [ "title" : string ]

    Alamofire.request("(url)", method: .post, parameters: Parameters).validate().responseString { response in
        if let anyResponse = response.result.value {
            self.responseFromServer = anyResponse
        }
        if self.responseFromServer == "" {
            completion(nil)
        } else {
            let ref = DatabaseReference.chats.reference()
            let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: (self.responseFromServer))
                query.observe(.childAdded, with: { snapshot in
                completion(Chat(dictionary: snapshot.value as! [String : Any]))
            })
        }
    }
}

Then you can call this function and use the return value like this:

findChat(string: "inputString", completion: { chat in
    if let chat = chat {
        //use the return value
    } else {
        //handle nil response
    }
})

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...