Unexpected non-void return value in void function swift 4 using json serialisation
You can't return data directly from an asynchronous task. Use a closure
Create a Function using a closure like.
func jsonSerialisation(jsonUrl: String, completion block: @escaping ((NSArray) -> ())){
let url = URL(string: JsonUrl)
let task = URLSession.shared.dataTask(with: url!) { (data, responce, error) in
if let e = error{
print(e.localizedDescription)
}
else{
if let content = data{
do {
if let Json = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSArray{
block(Json)
}
}
catch let error{
print(error.localizedDescription)
}
}
}
}
task.resume()
}
And Call :
jsonSerialisation(jsonUrl: "Your Url") { (json) in
print(json)
}
This is helpful
Unexpected non-void return value in void function when returns an array
You can´t just return words
in your closure
. First of all it´s an async method second you need to return a value outside of the closure which will be called before the closure. You need to have a completionHandler
instead of returning Array<Any>
. In that case you can pass the value if and when it succeeds. Something like this:
func getWords(onCompletion: @escaping (Array<Any>) -> Void) {
ref = Database.database().reference()
ref.child("addedWords").observe(.value, with: { (DataSnapshot) in
var tempWords = DataSnapshot.value as! [String:AnyObject]
var words = Array(tempWords.keys)
print(words)
onCompletion(words)
})
}
To call it:
getWords(onCompletion: { (words) in
print(words)
})
Unexpected non-void return value in void function (Swift 3)
If you are calling an async method like Alamofire.request
, then you need notify when this async method is over with closures
Try with this
func postUser(username: String, pass: String, finishedClosured:@escaping ((Bool)->Void)) {
Alamofire.request("https://someAPI.com/auth/login", method: .post, parameters: ["email": contact, "password": pass], encoding: URLEncoding.default, headers: ["Accept":"application/json"]).responseJSON { (response) in
switch(response.result) {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
print(json["data"]["result"])
finishedClosured(true)
case .failure(let error):
print(error)
finishedClosured(false)
}
}
}
Use it
self.postUser(username: "your UserName", pass: "Your Pass") { (result) in
if(result){
debugPrint("All is fine")
}else{
debugPrint("All is wrong")
}
}
Unexpected non-void return value in void function in request to server iOS Swift 3
You have implemented at least two async operations and they are can't return values. For async operations you should use completion handlers like this:
func sendRequest(urlString: String, method: String, completion: @escaping (_ dictionary: NSDictionary?, _ error: Error?) -> Void) {
DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string:urlString)!)
request.httpMethod = method
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
completion(nil, error)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
// make error here and then
completion(nil, error)
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
DispatchQueue.main.async {
do {
let jsonDictionary:NSDictionary = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] as NSDictionary
completion(jsonDictionary, nil)
} catch {
completion(nil, error)
}
}
}
task.resume()
}
}
Unexpected non-void return value in void function in request to server iOS Swift 3
You have implemented at least two async operations and they are can't return values. For async operations you should use completion handlers like this:
func sendRequest(urlString: String, method: String, completion: @escaping (_ dictionary: NSDictionary?, _ error: Error?) -> Void) {
DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string:urlString)!)
request.httpMethod = method
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
completion(nil, error)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
// make error here and then
completion(nil, error)
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
DispatchQueue.main.async {
do {
let jsonDictionary:NSDictionary = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] as NSDictionary
completion(jsonDictionary, nil)
} catch {
completion(nil, error)
}
}
}
task.resume()
}
}
How do I properly call a non-return-value Swift function when it also has an overloading version that has returned value?
As you discovered, you can guide type inferencing to use the overload that returns Void
by suppling a type. The other way to supply a type for type inferencing is to use the as
keyword. In your case, it would read doSomething() as Void
.
Return struct after parsing json in Swift
I found the solution. You have to add a closure and then use it when calling the function.
func getData(symbol: String, completion: @escaping (Stock) -> Void) {
let apiURL = "https://cloud.iexapis.com/stable/stock/\(symbol)/quote?token=\(secretToken)"
let url = URL(string: apiURL)!
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let json = try JSONDecoder().decode(Stock.self, from: data)
let stockResult = Stock(symbol: json.symbol,
companyName: json.companyName,
latestPrice: json.latestPrice
)
//I want to return this Stock structure
completionBlock(stockResult)
} catch let jsonErr {
print("Error serialising json: ", jsonErr)
}
}.resume()
}
then in the main you call
getData(symbol: "aapl") {(output) in
print(output)
}
How to return value from Alamofire
As mattt points out, Alamofire is returning data asynchronously via a “completion handler” pattern, so you must do the same. You cannot just return
the value immediately, but you instead want to change your method to not return anything, but instead use a completion handler closure pattern.
Nowadays, that might look like:
func getOrders(completionHandler: @escaping (Result<[String: Any]>) -> Void) {
performRequest("orders", completion: completionHandler)
}
func performRequest(_ section: String, completion: @escaping (Result<[String: Any]>) -> Void) {
let url = baseURL.appendingPathComponent(section)
let params = ["consumer_key": "key", "consumer_secret": "secret"]
Alamofire.request(url, parameters: params)
.authenticate(user: consumerKey, password: consumerSecret)
.responseJSON { response in
switch response.result {
case .success(let value as [String: Any]):
completion(.success(value))
case .failure(let error):
completion(.failure(error))
default:
fatalError("received non-dictionary JSON response")
}
}
}
Then, when you want to call it, you use this completion
closure parameter (in trailing closure, if you want):
api.getOrders { result in
switch result {
case .failure(let error):
print(error)
case .success(let value):
// use `value` here
}
}
// but don't try to use the `error` or `value`, as the above closure
// has not yet been called
//
IOS Swift How can I get value from an Async method
You can use a callback function for that like this:
func GetData(callback: (Int) -> Void) {
//Inside async task, Once you get the values you want to send in callback
callback(status)
}
You will get a callback from where you called the function.
For your situation, Anbu's answer will work too.
Related Topics
Swift Alamofire Return Value Is Empty
Declaring Conformance to @Objc Protocol in Empty Extension Breaks with Exc_Bad_Instruction
Avaudioplayer.Play() Works But Avaudioplayernode.Play() Fails
Replace Multiple Words from a String Based on the Values in an Array
Swift: Download Image from Internet and Cache Them Doesn't Work Properly. Need Suggestions
Show Datepicker Hourandminute on Print Statement Swiftui
How to Generate a Random Unicode Character in Swift
Arkit Setting Worldtrackingconfiguration to Gravityandheading Produces Error
Binary Operator '==' Cannot Be Applied to Operands of Type 'Uilabel' and 'String'
Swift - Associated Value or Extension for an Enum
Swift Function Compiler Error 'Missing Return'
Swiftui - Navigation View Opening with Back Button and Half Grey Screen/Weird Behavior
Interrupted Purchase Not Calling Delegate After Accepting T&C