我正在重构(尝试)前同事制作的一些网络代码,我想使用新的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
来手动测试了该行,错误消失了。
答案 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)