代码之家  ›  专栏  ›  技术社区  ›  armnotstrong

将json解码类型快速传递到http请求

  •  0
  • armnotstrong  · 技术社区  · 7 年前

    我想创建一个可以返回如下定义的stuct的静态func:

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

    我写了一个静态函数,如下所示:

    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

    如何解决这个问题?

    1 回复  |  直到 7 年前
        1
  •  4
  •   Robert Dresler Gustavo Vollbrecht    7 年前

    您要传递的是结构的类型,而不是协议。

    首先,为你的方法做一个通用的约束 T 必须遵守 Decodable (因为您需要它只是为了解码,所以不需要符合 Encodable )

    T.Type -这允许编译器 推断 类型 T ,可以避免使用此参数,请参见答案末尾的

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

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


    那么 JSONDecoder 的 decode 方法使用类型 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 ... }