如何在 Swift 4 中将可编码或可解码作为参数传递?



我正在学习JSONParsing。我遵循了教程,我得到的是这样的:

guard let url = URL(string: "http://localhost/test-api/public/api/register") else { return }
var request  = URLRequest(url: url)
request.httpMethod = "POST"
let newUser = User.init(name: self.collectionTF[0].text, email: self.collectionTF[1].text, password: self.collectionTF[2].text)
do {
let jsonBody = try JSONEncoder().encode(newUser)
request.httpBody = jsonBody
} catch { }
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else { return }
do {
let json = try JSONSerialization.jsonObject(with: data) as? [String:Any]
print(json!)
DispatchQueue.main.async {
if json!["status"] as! Int == 200
{
GeneralHelper.shared.keepLoggedIn()
NavigationHelper.shared.moveToHome(fromVC: self)
}
}
} catch { print(error.localizedDescription)}
}.resume()

好的,这就是我为注册所做的。现在,我想创建一个帮助程序,它将对@escaping做同样的事情,因为我都需要解析JSON作为回报。

因此,我将endPoint作为字符串传递,然后尝试传递这个Encodable的newUser,将来也可以是Decodable,但它Cannot invoke 'encode' with an argument list of type '(Codable)'抛出错误。谁能帮忙?而且,在涉及JSONParsing时多次调用此函数,这样更好吗?

编辑: - 所以,我现在正在使用networkRequestfunction,这是我所做的。

let newData = User.init(name: "Rob", email: "abc@gmail.com", password: "12345678")
ApiHelper.sharedInstance.networkRequest_Post(urlString: "register", header: nil, encodingData: newData) { (response: User, urlRes, error) in
<#code#> }

现在,它给了我这个错误:Cannot convert value of type '(User, _, _) -> ()' to expected argument type '(_?, HTTPURLResponse?, Error?) -> ()'.有什么帮助吗?

我在项目中使用了相同的功能

希望下面的代码会有所帮助

func networkRequest_Post<T: Decodable, Q: Encodable>(urlString: String,header:[String:String]?,encodingData: Q,completion: @escaping (T?, HTTPURLResponse?, Error?) -> ()) {
guard let url = URL(string: urlString) else { return }
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 300.0
config.timeoutIntervalForResource = 300.0
if header != nil{
config.httpAdditionalHeaders = header
}
let session = URLSession(configuration: config)
var request = URLRequest(url: url)
request.httpMethod = "POST"
do {
let jsonBody = try JSONEncoder().encode(encodingData)
request.httpBody = jsonBody
} catch {}
let task = session.dataTask(with: request) { (data,response, err) in
if let response = response {
print(response)
}
if let err = err {
print("Failed to fetch data:", err.localizedDescription, "Error Description(err)")
return
}
guard let data = data else { return }
do {
print(String(data: data, encoding: String.Encoding.utf8) as Any)
let dataReceived = try JSONDecoder().decode(T.self, from: data)
completion(dataReceived,response as? HTTPURLResponse,err)
} catch let jsonErr {
print("Failed to serialize json:", jsonErr, jsonErr.localizedDescription)
completion( nil,response as? HTTPURLResponse,jsonErr)
}
}
task.resume()
}

用-

let newdata = User(name: "Abhi", email: "jhjhj@jhj.co", password: "123hguhj")
networkRequest_Post(urlString: "YOUR_URL", header: nil, encodingData: newdata) { (RESPONSE_DATA:User?, URL_RESPONSE, ERROR) in
// Do your network work here
}
struct User : Codable {
var name: String?
var email: String?
var password: String?
}

您可以通过以下方式使用泛型...

func requestWith<T>(method: HTTPMethod, action: String,  params: Parameters?, for type: T.Type, success: @escaping (AnyObject) -> Void, failure: @escaping (AnyObject) -> Void) where T: Codable {

//do your stuff..your logic goes here..see below example
guard let serverData = response.data else {
return
}
do {
let decoder = JSONDecoder()
let responseData = try decoder.decode(type, from: serverData)
success(responseData as AnyObject)
} catch {
print("Error = (error.localizedDescription)")
failure(error.localizedDescription as AnyObject)
}
}

最新更新