如何在 Swift 中实现解码泛型函数
How to make decoding generic function in Swift
我必须从 Alamofire 获取一些 json 并将它们保存到我制作的不同结构中,但我找不到只为我需要制作的所有请求制作一个方法的方法。这是我的方法
func fetchData(url: String, parameters: [String : Any], finished: @escaping (EmployeeCompositionApp) -> Void) {
Alamofire.request(url,
method: .post,
parameters: parameters).responseJSON(completionHandler: { response in
guard response.result.error == nil else {
print("Error en la petición a Alamofire:\n \(String(describing: response.result.error))")
return
}
guard let json = response.result.value as? [String : Any] else {
if let error = response.result.error {
print("Error: \(error.localizedDescription)")
}
return
}
do {
let decoder = JSONDecoder()
let rawData = try JSONSerialization.data(withJSONObject: json, options: [])
let dataObject = try decoder.decode(EmployeeCompositionApp.self, from: rawData)
finished(dataObject)
} catch let error {
print("Error")
}
})
}
但是当我尝试将 EmployeeCompositionApp
替换为 Any
或任何其他通用类型以便我可以将其与其他对象一起使用时,Xcode 说
Cannot invoke 'decode' with an argument list of type '(Any, from: Data)'
我该怎么做?
你只需要类型是Decodable
:
func fetchData<T: Decodable>(url: String, parameters: [String : Any], finished: @escaping (T) -> Void) {
然后
let dataObject = try decoder.decode(T.self, from: rawData)
另请注意,使用 Alamofire
将 JSON 数据转换为字典然后将其编码回 Data
是没有意义的,因此您可以使用 JSONDecoder()
.使用 .responseData
而不是 .responseJSON
:
func fetchData<T: Decodable>(url: String, parameters: [String : Any], finished: @escaping (T) -> Void) {
Alamofire.request(
url,
method: .post,
parameters: parameters
).responseData { response in
guard
response.result.error == nil,
let data = response.result.value
else {
print("Error en la petición a Alamofire:\n \(String(describing: response.result.error))")
return
}
do {
let decoder = JSONDecoder()
let dataObject = try decoder.decode(T.self, from: data)
finished(dataObject)
} catch {
print("Error")
}
}
}
另请注意,当发生错误时,您应该以某种方式将该信息返回给调用者,而不仅仅是打印错误。
我必须从 Alamofire 获取一些 json 并将它们保存到我制作的不同结构中,但我找不到只为我需要制作的所有请求制作一个方法的方法。这是我的方法
func fetchData(url: String, parameters: [String : Any], finished: @escaping (EmployeeCompositionApp) -> Void) {
Alamofire.request(url,
method: .post,
parameters: parameters).responseJSON(completionHandler: { response in
guard response.result.error == nil else {
print("Error en la petición a Alamofire:\n \(String(describing: response.result.error))")
return
}
guard let json = response.result.value as? [String : Any] else {
if let error = response.result.error {
print("Error: \(error.localizedDescription)")
}
return
}
do {
let decoder = JSONDecoder()
let rawData = try JSONSerialization.data(withJSONObject: json, options: [])
let dataObject = try decoder.decode(EmployeeCompositionApp.self, from: rawData)
finished(dataObject)
} catch let error {
print("Error")
}
})
}
但是当我尝试将 EmployeeCompositionApp
替换为 Any
或任何其他通用类型以便我可以将其与其他对象一起使用时,Xcode 说
Cannot invoke 'decode' with an argument list of type '(Any, from: Data)'
我该怎么做?
你只需要类型是Decodable
:
func fetchData<T: Decodable>(url: String, parameters: [String : Any], finished: @escaping (T) -> Void) {
然后
let dataObject = try decoder.decode(T.self, from: rawData)
另请注意,使用 Alamofire
将 JSON 数据转换为字典然后将其编码回 Data
是没有意义的,因此您可以使用 JSONDecoder()
.使用 .responseData
而不是 .responseJSON
:
func fetchData<T: Decodable>(url: String, parameters: [String : Any], finished: @escaping (T) -> Void) {
Alamofire.request(
url,
method: .post,
parameters: parameters
).responseData { response in
guard
response.result.error == nil,
let data = response.result.value
else {
print("Error en la petición a Alamofire:\n \(String(describing: response.result.error))")
return
}
do {
let decoder = JSONDecoder()
let dataObject = try decoder.decode(T.self, from: data)
finished(dataObject)
} catch {
print("Error")
}
}
}
另请注意,当发生错误时,您应该以某种方式将该信息返回给调用者,而不仅仅是打印错误。