无法使用类型为((Codable.Type?

时间:2019-01-22 14:19:54

标签: json swift deserialization jsondecoder

我正在重构(尝试)前同事制作的一些网络代码,我想使用新的JSONDecoder

他的网络代码包装在函数getData中:

func getData(modelToReturn:Proto.Type, configuredRequest:URLRequest) {

从签名中可以看到,在此方法中,您可以指定要返回的模型(即该模型应该对检索到的JSON进行反序列化:我不能说得更好,无论如何我希望您理解:-) )。

在这种情况下,Proto是任何模型都遵循的协议。

例如

struct GroceryModel:Proto{
  //...
}

然后以这种方式调用该方法:

net.getData(modelToReturn: GroceryModel.self, configuredRequest: grocery)

一旦调用,GroceryModel.self被分配给net类(memberToReturn:Proto.Type?)的成员,然后JSON测试了其是否与初始化失败的模型结构相符:

 if let instance = modelToReturn?.init(json:jsonResult){...

我使用以下协议进行了一些测试:

struct Test: Codable {
    let name: String
    let testers: [String]
}

我用这一行替换了很多原始代码:

let test = try? JSONDecoder().decode(modelToReturn, from: jsonData)

我的想法是将Codable.self作为getData函数的第一个参数传递,但在最后一行出现错误:

Cannot invoke 'decode' with an argument list of type '(Codable.Type?, from: Data)'

那么,如何正确传递模型,以便可以从decode函数中使用它?

我必须说,我通过简单地将modelToReturn替换为Test.self来手动测试了该行,错误消失了。

1 个答案:

答案 0 :(得分:0)

您可以使用以下通用名称。

protocol Proto {
}

struct Test: Codable, Proto {
    let name: String
    let testers: [String]
}

func getData<T>(type: T.Type, configuredRequest:URLRequest?) where T : Decodable {
    let data = """
{
    "name": "a test",
    "testers": ["mike", "bob"],
}
""".data(using: .utf8)!
    let test = try? JSONDecoder().decode(type, from: data)
    debugPrint(test)
}

getData(type: Test.self, configuredRequest: nil)

已编辑。

如前所述,您希望Type成为具有getData的类的成员。 在这种情况下,您可以将泛型应用于类定义,如下所示。

class DataFetcher<T> where T: Decodable {
    func getData(configuredRequest:URLRequest?) {
        let data = """
{
    "name": "a test",
    "testers": ["mike", "bob"],
}
""".data(using: .utf8)!
        let test = try? JSONDecoder().decode(T.self, from: data)
        debugPrint(test)
    }
}

DataFetcher<Test>().getData(configuredRequest: nil)