带有 Alamofire 的泛型函数



我使用使用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('的参数列表调用'解码'">

"转义闭包只能按值显式捕获 inout 参数">

将这些编写为泛型的最佳方法是什么?

经过几次搜索并尝试编辑我的函数,我能够重写我的两个函数,以便我得到我需要的东西:

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
}

对于第一个函数,JSONDecoder.decode(( 需要 2 个参数:

  • 要解码的类型:您希望它解码到的类/结构。这不是实例化的对象,只是类型。
  • 要从中解码的数据:将转换为指定类型的通用 Data 对象。

因此,为了能够编写函数,使其具有通用 URL 和结果对象,您需要将对象类型和回调传递给它以将结果传递给它,因为网络操作是异步的。

func dec<T: Decodable>(from: URL, decodable: T.Type, result: (T) -> Void) { 
// your Alamofire logic
let data = try JSONDecoder().decode(popedList, from: result!)
result(data)
}

您可以将相同的逻辑应用于第二个函数。

请注意,这不是处理最终错误的最佳方法,只是如何使用泛型函数处理编码的示例。

JSONDecoder().decode方法采用类型和数据参数。通行证类型不popedList

let data = try JSONDecoder().decode([T].self, from: result!)

默认情况下,输入参数函数参数为常量。尝试从函数主体中更改函数参数的值会导致编译时错误。这意味着您不能错误地更改参数的值。如果希望函数修改参数的值,并且希望在函数调用结束后保留这些更改,请改为将该参数定义为 in-out 参数。

您不会在两个函数中更改popedList的值,因此使用inout毫无意义。

相关内容

  • 没有找到相关文章

最新更新