0

The following code doesn't compile:

public protocol Foo: Decodable {
  var message: String { get }
}
struct Bar: Foo {
  let message: String
}

// the type conforming Foo protocol is passed from somewhere
let type: Foo.Type = Bar.self
decode(type: type, from: Data())

func decode<T>(type: T.Type, from data: Data) Where T: Decodable {
  let decoder = JSONDecoder()
  try! decoder.decode(type, from: data)
}

it throws the error: Cannot invoke 'decode' with an argument list of type '(Foo.Type, from: Data)'

Do you guys have any idea?

faintsignal
  • 1,828
  • 3
  • 22
  • 30
jaychang0917
  • 1,880
  • 1
  • 16
  • 21

2 Answers2

3

You can use like this :

public protocol Foo: Decodable {
    var message: String { get }
}
struct Bar: Foo {
    let message: String
}

class ViewController: UIViewController {
    let bar = """
        {"message": "Sample message"}
    """

    override func viewDidLoad() {
        super.viewDidLoad()
        let type = Bar.self
        decode(type: type, from: bar.data(using: .utf8)!)
    }

    func decode<Foo>(type: Foo.Type, from data: Data) where Foo: Decodable {
        let decoder = JSONDecoder()
        let parsedData = try! decoder.decode(type, from: data)
        print(parsedData)
    }
}
Vini App
  • 7,339
  • 2
  • 26
  • 43
  • How to make this compile? ```let type: Foo.Type = Bar.self decode(type: type, from: bar.data(using: .utf8)!)```, it is because the **type** is passed from somewhere, the concrete type is unknown, the only thing I know it is conformed `Foo` – jaychang0917 Oct 14 '17 at 04:57
  • Are you getting any issues? – Vini App Oct 14 '17 at 05:32
2

You should use Codable on your Bar for this instead:

protocol Foo {
    var message: String { get }
}
struct Bar: Foo, Codable {
    let message: String
}

Usage:

let bar = Bar(message: "Just a message")
if let data = try? JSONEncoder().encode(bar) {
    print(String(data:data, encoding:.utf8) ?? "") // {"message":"Just a message"}\n"// lets decode it
    if let decodedBar = try? JSONDecoder().decode(Bar.self, from: data) {
        print(decodedBar.message) //"Just a message\n"
     }
}
Rashwan L
  • 38,237
  • 7
  • 103
  • 107