简体   繁体   English

使用Codable和JSONParser进行通用网络解码

[英]Generic networking decoding with Codable & JSONParser

i have 2 main parts in my app infrastructure. 我的应用程序基础结构中有2个主要部分。

NetworkingManager
NetworkRequest

My goal is to have the request hold its Codable Type so when networking is done the Manager layer can instantiate new instance with the correct type by using 我的目标是让请求保留其Codable Type以便在完成网络连接后, Manager层可以使用实例化具有正确类型的新实例。

decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable

so my NetworkRequest look like so 所以我的NetworkRequest看起来像这样

class NetworkRequest {
  var objectClass:Codable.Type
}

lets say i have a Person class which conforms to Codable 可以说我有一个符合CodablePerson

class Person : Codable {
 var name:String?
}

now i need to assign the type into the request like so (in an ugly way to get to the point here) 现在我需要像这样将类型分配给请求(以一种丑陋的方式来说明这一点)

let request = NetworkingRequest()
request.objectClass = Person.self

now when i want the NetworkingManager to decode the response i use it like so: 现在,当我希望NetworkingManager解码响应时,我将其像这样使用:

JSONDecoder().decode(type:request.objectClass, data:dataFromService)

the problem is when i do so i get this error: 问题是当我这样做时出现此错误:

Cannot invoke decode with an argument list of type (Decodable.Type, from: Data). 无法使用类型为(Decodable.Type,来自:Data)的参数列表调用解码。 Expected an argument list of type (T.Type, from: Data). 预期类型为(T.Type,来自:数据)的参数列表。

any help would be appreciated 任何帮助,将不胜感激

Try something like this: 尝试这样的事情:

class NetworkRequest<T: Codable> {
    var objectClass: T.Type

    init(objectClass: T.Type) {
        self.objectClass = objectClass
    }
}

Does marking NetworkRequest as a genric <T: Codeable> do what you need? NetworkRequest标记为通用<T: Codeable>是否<T: Codeable>您的需求?

class NetworkRequest<T: Codable> {
    var objectClass: T.Type
}

Then initing and calling like 然后像这样发起和调用

let request = NetworkRequest<Person>()
request.objectClass = Person.self

And calling 并打电话

try JSONDecoder().decode(request.objectClass, from: dataFromService)
class NetworkRequest<T: Codable> {
    var objectClass: T.Type!

    init(objectClass : T.Type) {
        self.objectClass = objectClass
    }

}

class Person : Codable {
    var name:String?
}

let request = NetworkRequest<Person>(objectClass: Person.self)

let response : Dictionary<String,Any> = ["name":"test"]
let data : Data = try! JSONSerialization.data(withJSONObject: response,options: [])

do {
    let person = try JSONDecoder().decode(request.objectClass, from: data)
    print(person.name ?? "--")
} catch {
    print(error)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM