迅速通JSON解码类型http请求

问题描述 投票:0回答:1

我想使静态FUNC时可能会返回类似这样定义的结构:

struct Category: Codable {
    public let data: Array<CateItem>
    public let status: Int
    public let msg: String
}

我有写一个静态的FUNC这样的:

static func Get(codePoint: String, responseType: Codable){
    let urlString = UrlUtils.GetUrl(codePoint: codePoint)
    let url = URL(string: urlString)
    let task = URLSession.shared.dataTask(with: url!){
        (data,response,error) in
        if error != nil{
            print(error!)
        }else{
            if let data = data{
                JSONDecoder().decode(responseType, from: data)
            }
        }
    }
    task.resume()
}

并调用这样的方法:

HttpRequests.Get(codePoint: "getCategoryList", responseType:  Category)

但这里responseType将无法正常工作。

如何解决这一问题?

json swift
1个回答
4
投票

你想传递结构,而不是协议的类型。

首先,为您的方法,说T必须符合Decodable(因为你需要它只是用于解码,你不需要符合Encodable)泛型约束

然后说,参数的类型应该T.Type的 - 这允许编译器推断T的类型,你能避免使用此参数,请在答案的结尾

static func Get<T: Decodable>(codePoint: String, responseType: T.Type) { ... }

...所以T将是你会传递给方法的类型。


那么对于JSONDecoderdecode方法使用类型T

JSONDecoder().decode(T.self, from: data)

然后当你想打电话给你的方法,通过你的结构类型像你解码内做到了

HttpRequests.Get(codePoint: "getCategoryList", responseType: Category.self)

另外请注意,您的电话是异步所以返回的数据,你需要完成处理程序定义为您的方法的参数

completion: @escaping (T?) -> Void

注意,方法名称应以小型大写字母开始

static func get<T: Decodable>(codePoint: String, responseType: T.Type, completion: @escaping (T?) -> Void) {

    let urlString = UrlUtils.GetUrl(codePoint: codePoint)
    let url = URL(string: urlString)

    URLSession.shared.dataTask(with: url!) { data, response, error in

        guard let data = data else {
            print(error!)
            return completion(nil)
        }

        do {
            let decoded = try JSONDecoder().decode(T.self, from: data)
            completion(decoded)
        } catch {
            print(error)
            completion(nil)
        }
    }.resume()
}

HttpRequests.get(codePoint: "getCategoryList", responseType: Category.self) { response in
    if let category = response {
        ...
    }
}

您也可以尽量避免使用responseType参数,因为T的类型可以从完成封闭参数的类型推断

static func get<T: Codable>(codePoint: String, completion: @escaping (T?) -> Void) { ... }

HttpRequests.get(codePoint: "getCategoryList") { (category: Category?) -> Void in ... }
© www.soinside.com 2019 - 2024. All rights reserved.