【问题标题】:How to make decoding generic function in Swift [duplicate]如何在Swift中制作解码通用函数[重复]
【发布时间】:2019-08-09 08:07:56
【问题描述】:

我必须从 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)'

我该怎么做?

【问题讨论】:

  • 您应该使用符合<T:Codable><T:Decodable> 的类型

标签: swift function methods alamofire decoding


【解决方案1】:

你只需要类型是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")
        }
    }
}

还要注意,当发生错误时,您应该以某种方式将该信息返回给调用者,而不仅仅是打印错误。

【讨论】:

  • 非常感谢!这解决了我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 2011-09-03
  • 1970-01-01
  • 2020-03-08
  • 2021-01-21
  • 1970-01-01
相关资源
最近更新 更多