JSONEncoder's dateEncodingStrategy no funciona

Estoy tratando de serializar una estructura a una Cadena usando Encodable + JSONEncoder de Swift 4. El objeto puede contener valores heterogéneos como String, Array, Date, Int, etc.

El enfoque utilizado funciona bien con la excepción de Date. JSONEncoder'sdateEncodingStrategy La propiedad no tiene ningún efecto.

Aquí hay un fragmento que reproduce el comportamiento en Playground:

struct EncodableValue:Encodable {
    var value: Encodable

    init(_ value: Encodable) {
        self.value = value
    }

    func encode(to encoder: Encoder) throws {
        try value.encode(to: encoder)
    }
}

struct Bar: Encodable, CustomStringConvertible {
    let key: String?
    let value: EncodableValue?

    var description: String {
        let encoder = JSONEncoder()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "E, d MMM yyyy"
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        encoder.dateEncodingStrategy = .formatted(dateFormatter)
        let jsonData = try? encoder.encode(self)
        return String(data: jsonData!, encoding: .utf8)!
    }
}

let bar1 = Bar(key: "bar1", value: EncodableValue("12345"))
let bar2 = Bar(key: "bar2", value: EncodableValue(12345))
let bar3 = Bar(key: "bar3", value: EncodableValue(Date()))

print(String(describing: bar1))
print(String(describing: bar2))
print(String(describing: bar3))

Salida:

"{"key":"bar1","value":"12345"}\n"
"{"key":"bar2","value":12345}\n"
"{"key":"bar3","value":539682026.06086397}\n"

Para el objeto bar3: espero algo como"{"key":"bar3","value":"Thurs, 3 Jan 1991"}\n", pero devuelve la fecha en el formato de estrategia predeterminado .deferToDate.

## EDIT 1 ##

Así que ejecuté el mismo código en XCode 9 y da el resultado esperado, es decir, formatea correctamente la fecha en cadena. Estoy pensando que 9.2 tiene una actualización menor a Swift 4 que está rompiendo esta característica. No estás seguro de qué hacer después.

## EDIT 2 ##

Como remedio temporal, usé el siguiente fragmento antes de cambiar al enfoque de @ Hamish usando un cierre.

struct EncodableValue:Encodable {
    var value: Encodable

    init(_ value: Encodable) {
        self.value = value
    }

    func encode(to encoder: Encoder) throws {
        if let date = value as? Date {
            var container = encoder.singleValueContainer()
            try container.encode(date)
        }
        else {
            try value.encode(to: encoder)
        }

    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta