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

Cannot invoke 'decode' with an argument list of type '(Codable.Type?

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

他的网络代码被包装成一个函数getData:

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

正如你从签名中看到的那样,在这个方法中你可以将模型指定为return(即哪个模型应该反序列化检索到的JSON:我不能说更好,我希望你能理解 :-)).

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

例如

struct GroceryModel:Proto{
  //...
}

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

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

调用后,GroceryModel.self 被分配给 net class (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 手动测试了该行,错误消失了。

您可以像下面这样使用泛型。

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 成为 class 的成员,该 class 具有 getData。 在这种情况下,您可以将泛型应用于 class 定义,如下所示。

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)