orthehelper
orthehelper

Reputation: 4079

Generic networking decoding with Codable & JSONParser

i have 2 main parts in my app infrastructure.

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

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

so my NetworkRequest look like so

class NetworkRequest {
  var objectClass:Codable.Type
}

lets say i have a Person class which conforms to Codable

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:

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). Expected an argument list of type (T.Type, from: Data).

any help would be appreciated

Upvotes: 0

Views: 223

Answers (3)

Pratik Sodha
Pratik Sodha

Reputation: 3727

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)
}

Upvotes: 1

mmr118
mmr118

Reputation: 505

Does marking NetworkRequest as a genric <T: Codeable> do what you need?

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)

Upvotes: 1

cocavo
cocavo

Reputation: 163

Try something like this:

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

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

Upvotes: 1

Related Questions