avaz
avaz

Reputation: 543

Swift dynamic type invoking, how?

The following code doesn't compile:

import Foundation
import PlaygroundSupport

protocol C : Decodable {
}

class A : C {
    let code: Int

}

class B : C {
    let blob: Int
}

var c : C.Type
let a = A.self
let b = B.self
let i = 100
if i == 100 {
    c = a
}
else if i < 100 {
    c = b
}
do {
    let data = String("{\"code\": 123}").data(using: .utf8)!
    let j = try JSONDecoder().decode(c, from: data)
    print(j)
}
catch let error as NSError{
    print(error.debugDescription)
}

The error is:

cannot invoke 'decode' with an argument list of type '(C.Type, from: Data)' let j = try JSONDecoder().decode(c, from: data)

What would be the proper way to declare the c variable so it could receive or type A or type B and still complies with JSONDecoder().decode(...) signature?

Upvotes: 1

Views: 95

Answers (1)

Rob Napier
Rob Napier

Reputation: 299605

(Bah; never mind my old answer. Hamish is right.)

Add an extension:

extension C {
    static func decode(data: Data) throws -> C {
        return try JSONDecoder().decode(Self.self, from: data)
    }
}

Decode with it:

let j = try c.decode(data: data)

EDIT: I'm not certain what you mean by it not compiling against your code. Perhaps because you have another bug (you don't initialize c in all legs). Here is what I'm describing, based on your code:

import Foundation
import PlaygroundSupport

protocol C : Decodable {
}

// Adding extension
extension C {
    static func decode(data: Data) throws -> C {
        return try JSONDecoder().decode(Self.self, from: data)
    }
}

class A : C {
    let code: Int

}

class B : C {
    let blob: Int
}

var c : C.Type = A.self // You have to initialize this for all legs
let a = A.self
let b = B.self
let i = 100
if i == 100 {
    c = a
}
else if i < 100 {
    c = b
}
do {
    let data = String("{\"code\": 123}").data(using: .utf8)!
    // Rewrite this line
    let j = try c.decode(data: data)
    print(j)
}
catch let error as NSError{
    print(error.debugDescription)
}

Upvotes: 1

Related Questions