我正在尝试在swift 3上创建一个回调,但到目前为止还没有任何运气。我正在看一下这个问题:link这是类似的,但答案给了我一个错误。
基本上我有一个带有静态函数的API结构,我需要回调。
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()
}
}
所以我基本上无法调用回调成功,因为它给了我一个错误:调用中的额外参数。有关如何修复的想法吗?
我的目标是致电:
API.functionWithCallback(params: params, success() -> Ticket {
//do something with the returned ticket here
},
error() -> () {
//do something with the error message here
}
)
答案 0 :(得分:2)
我相信你对如何使用回调闭包有错,从我能理解你的问题你想要在回调闭包中对票做一些事情并且这样做它应该是闭包的一个参数不是封闭的返回类型。
用以下代码替换你的函数声明:
public static func functionWithCallback(params: Dictionary<String, String>, success: @escaping ((_ response: String, _ ticket: Ticket) -> Void), failure: @escaping((_ error:String) -> Void) ) {
在函数内部替换:
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
}
使用:
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)
然后你可以这样调用这个函数:
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
}
答案 1 :(得分:0)
试试这个:
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
}
和函数调用是:
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)
}
}