我与使用Alamofire的iOS应用一起工作,我想编写一个通用函数,该函数用于从服务器向可解码对象发送和检索数据,我的功能如下:
func pop <T : Codable> (_ Url: inout String, _ popedList: inout [T]) {
let url = URL(string:Url)
Alamofire.request(url!, method: .post).responseJSON { response in
let result = response.data
do {
let data = try JSONDecoder().decode(popedList, from: result!)// get error here
print(data[0])
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(data[0])
let jsonString = String(data: jsonData, encoding: .utf8)
print("jsonString: \(String(describing: jsonString))")
} catch let e as NSError {
print("error : \(e)")
}
}
}
以及将对象发送到服务器的函数,如下所示:
func push <T : Codable> (_ Url: inout String, _ pushObject: inout T) {
let jsonData = try! JSONEncoder().encode(pushObject)
let jsonString = String(data: jsonData, encoding: .utf8)
print("jsonString: \(String(describing: jsonString))")
let url = URL(string:Url)
Alamofire.request(url!,
method: .post,
parameters:jsonString)//it's need to creat a Dictionary instate of String
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { response in
// response handling code
let result = response.data
print(response.data)
}
}
我在第一个函数中遇到错误
“无法使用类型为'([T],from:Data)'的参数列表调用'decode'”
和
“转义的闭包只能按值显式捕获inout参数”
编写这些文件以使其具有通用功能的最佳方法是什么?
答案 0 :(得分:2)
经过几次搜索并尝试编辑我的函数后,我能够立即重写两个函数,以得到所需的东西:
func pop<T: Decodable>(from: URL, decodable: T.Type, completion:@escaping (_ details: [T]) -> Void)
{
Alamofire.request(from, method: .post).responseJSON { response in
let result_ = response.data
do {
let data = try JSONDecoder().decode([T].self, from: result_!)
//let data = try JSONDecoder().decode(decodable, from: result_!)// get error here
//print(data[0])
print("data[0] : \(data[0])")
completion(data)
} catch let e as NSError {
print("error : \(e)")
}
}
}
func push <T : Codable> (_ Url: String, _ pushObject: T)
{
let jsonData = try! JSONEncoder().encode(pushObject)
let jsonString = String(data: jsonData, encoding: .utf8)
print("jsonString: \(String(describing: jsonString))")
let url = URL(string:Url)
Alamofire.request(url!,
method: .post,
parameters:convertToDictionary(text: jsonString!))//it's need to creat a Dictionary instate of String
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { response in
// response handling code
print(response.data!)
if let jsonData = response.data {
let jsonString = String(data: jsonData, encoding: .utf8)
print("response.data: \(String(describing: jsonString))")
}
}
}
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
答案 1 :(得分:0)
JSONDecoder().decode
方法采用类型和数据参数。密码类型不是popedList
。
let data = try JSONDecoder().decode([T].self, from: result!)
Inout参数 函数参数默认为常量。试图从函数主体内部更改函数参数的值会导致编译时错误。这意味着您不能错误地更改参数的值。如果您希望函数修改参数的值,并且希望这些更改在函数调用结束后仍然存在,请将该参数定义为输入输出参数。
您没有在两个函数中都更改popedList
的值,因此使用inout
毫无意义。
答案 2 :(得分:0)
对于第一个功能,JSONDecoder.decode()需要2个参数:
因此,由于网络操作是异步的,因此为了能够编写具有通用URL和结果对象的函数,您需要将其传递给对象类型和回调以将结果传递给该函数。 / p>
#import <CommonCrypto/CommonHMAC.h>
您可以将相同的逻辑应用于第二个功能。
请注意,这并不是解决最终错误的最佳方法,只是一个如何使用通用函数处理编码的示例。