0

I am trying to create a callback on swift 3 but haven't had any luck so far. I was taking a look at this question: link which is similar, but the answer gives me an error.

Basically I have an API struct with a static function that I need to have a callback.

import UIKit struct API { public static func functionWithCallback(params: Dictionary<String, String>, success: @escaping ((_ response: String) -> Ticket), failure: @escaping((_ error:String) -> String) ) { let app_server_url = "http://api.com" + params["key"]! let url: URL = URL(string: app_server_url)! var request: URLRequest = URLRequest(url: url) request.httpMethod = "POST" do { request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted) } catch let error { print(error.localizedDescription) } request.addValue("application/json charset=utf-8", forHTTPHeaderField: "Content-Type") request.addValue("application/json charset=utf-8", forHTTPHeaderField: "Accept") let session = URLSession.shared let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in guard error == nil else { return } guard let data = data else { return } DispatchQueue.main.async { do { let json = try JSONSerialization.jsonObject(with: data) as! [String: Any] print(json) var message = "" if let result = json["result"] as? String { if(result == "success") { //attempt to call callback gives me an error: extra argument in call success("") { let ticket = json["ticket"] as! NSDictionary var date = ticket["date"] as! String var ticket: Ticket = nil ticket.setDate(date: date) return ticket } } else { message = json["message"] as! String print(message) } } catch let error { print(error.localizedDescription) let description = error.localizedDescription if let data = description.data(using: .utf8) { do { let jsonError = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] let message = jsonError?["message"] as! String } catch { } } } } }) task.resume() } } 

So I basically can't call the callback success because it gives me an error: Extra argument in call. Any idea on how to fix it?

My goal is to call:

API.functionWithCallback(params: params, success() -> Ticket { //do something with the returned ticket here }, error() -> () { //do something with the error message here } ) 
2
  • There are tons of errors. Commented Aug 18, 2017 at 13:02
  • There might be. I edited the question within the browser to remove unnecessary code, but it gives you the idea. Commented Aug 18, 2017 at 13:20

2 Answers 2

3

I believe you have it wrong on how to use call back closures, from what I can understand of your question you want to do something with the ticket in the call back closure and to do that it should be a parameter of the closure not the return type of the closure.

Replace your function declaration with this:

public static func functionWithCallback(params: Dictionary<String, String>, success: @escaping ((_ response: String, _ ticket: Ticket) -> Void), failure: @escaping((_ error:String) -> Void) ) { 

And inside the function replace this:

success("") { let ticket = json["ticket"] as! NSDictionary var date = ticket["date"] as! String var ticket: Ticket = nil // Im not sure what you are trying to do with this line but this will definitely give an error ticket.setDate(date: date) return ticket } 

With:

let ticket = json["ticket"] as! NSDictionary var date = ticket["date"] as! String var ticket: Ticket = nil // fix this line ticket.setDate(date: date) success("",ticket) 

And then you can call the function like this:

API.functionWithCallback(params: params, success: { response, ticket in // you can use ticket here // and also the response text }) { errorMessage in // use the error message here } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! That's what I am looking for! It works now.
0

Try this :

func uploadImage(api: String,token : String, methodType : String, requestDictionary: [String:AnyObject],picData:[Data], successHandler: @escaping (AnyObject) -> Void,failureHandler: @escaping (NSError) -> Void) { if Common_Methods.Reachability1.isConnectedToNetwork() == false { let del :AppDelegate = (UIApplication.shared.delegate as? AppDelegate)! let nav : UINavigationController = (del.window?.rootViewController as? UINavigationController)! let alert = UIAlertController(title: "", message: "The Internet connection appears to be offline" , preferredStyle: UIAlertControllerStyle.alert) // Create the actions let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { UIAlertAction in } alert.addAction(okAction) nav.present( alert, animated: true, completion: nil) return } let apiUrl = "\(KbaseUrl)\(api)" let session = URLSession.shared let url: NSURL = NSURL(string: apiUrl as String)! print(url) let request = NSMutableURLRequest(url: url as URL) request.httpMethod = methodType let boundary = NSString(format: "---------------------------14737809831466499882746641449") as String //-------- add token as perameter and set a check if token not nill then set token in header ------- if(token.characters.count > 0) { request.setValue(token, forHTTPHeaderField: "x-logintoken") } request.setValue("Keep-Alive", forHTTPHeaderField: "Connection") request.setValue("multipart/form-data; boundary="+boundary, forHTTPHeaderField: "Content-Type") let data = createBodyWithParameters(parameters: requestDictionary, filePathKey:nil, imageDataKey: picData.count > 0 ? picData : [], boundary: boundary) print(data) request.httpBody = data let task = session.dataTask(with: request as URLRequest) { data, response, error in // handle fundamental network errors (e.g. no connectivity) guard error == nil && data != nil else { successHandler(data as AnyObject )//completion(data as AnyObject?, error as NSError?) print(error) DispatchQueue.main.async { Common_Methods.hideHUD(view: (topVC?.view)!) } return } // check that http status code was 200 if let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode != 200 { do { let responseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary if let responseDictionary = responseObject as? [String:AnyObject] { if responseDictionary["statusCode"] as! Int == 401 { // self.objDelegate.sessionExpire(msgStr: "Session Expired. Please login again to continue.") } else { //completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, nil) } } } catch let error as NSError { print(error) DispatchQueue.main.async { Common_Methods.hideHUD(view: (topVC?.view)!) } // completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, nil) } } // parse the JSON response do { DispatchQueue.main.async { Common_Methods.hideHUD(view: (topVC?.view)!) } let responseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary successHandler(responseObject! ) } catch let error as NSError { DispatchQueue.main.async { Common_Methods.hideHUD(view: (topVC?.view)!) } // completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, error) failureHandler(error) } } task.resume() // return task } 

and function Call is :

WebService.sharedInstance.uploadImage(api: KEditEmployerProfile,token: token,methodType: "PUT", requestDictionary: parameters1 as! [String : AnyObject], picData: [imageData as Data], successHandler: { (responseObject) in print(responseObject) }) { (error) in print(error) } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.