1

I'm playing around with the new Codable protocol and JSONEncoder

The following method throws an odd exception:

  private func generateJSONData(body: [String: Codable]?) -> Data? {
    guard let body = body else {
      print("empty body for json encoding")
      return nil
    }

    let encoder = JSONEncoder()
    do {
     let data = try encoder.encode(body)
      return data
    } catch {
      print("error encoding body to json")
      return nil
    }
  }

fatal error: Dictionary<String, Decodable & Encodable> does not conform to Encodable because Decodable & Encodable does not conform to Encodable.

This even gets funnier when I change the signature to

private func generateJSONData(body: [String: Encodable]?)

fatal error: Dictionary<String, Encodable> does not conform to Encodable because Encodable does not conform to Encodable.:

The interesting thing is that this works fine with [String: String]

Is there a reason [String: Codable] is not codable?

Hamish
  • 78,605
  • 19
  • 187
  • 280
Reza Shirazian
  • 2,303
  • 1
  • 22
  • 30
  • Its because protocols don't conform to themselves.See [here](https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself/) – LC 웃 Jun 11 '17 at 06:06
  • And the solution, as I demonstrate [in my answer to the linked Q&A](https://stackoverflow.com/a/43408193/2976878), is to create a type-erased wrapper `AnyEncodable` that conforms to `Encodable` and forwards calls to `encode(to:)` to an underlying `Encodable` instance. Although that being said, given the compiler magic already in place around the `Codable` API, I wouldn't be surprised if they made a special exception for `Encodable` conforming to `Encodable` in a future build (and hopefully this leads to a more general "any protocol with non-static requirements can conform to itself"). – Hamish Jun 11 '17 at 08:46

0 Answers0