2

I'm trying to serialize my objects with the Swift 4.0 Codable protocol. I'm hitting an error when trying to decode closure properties:

guard let influenceFunction = try? container.decode(((E, Double) -> (E))!.self, forKey: TransformCodingKeys.influenceFunction) else {
    // ... do something clever ...
    print("sad times...")
}

Cannot invoke 'decode' with an argument list of type '(((E, Double) -> (E))!.Type, forKey: TransformCodingKeys)'

Understandable enough, I suppose, but surely there must be some strategy I can use (after all, functions are first-class objects, right?). Do I have to wrap my closures somehow?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
jbm
  • 1,248
  • 10
  • 22
  • What are you trying to decode? `(E, Double) -> (E)` doesn’t conform to `Decodable` and I don’t see how that could be represented in JSON, etc. – Paolo Aug 30 '17 at 23:55
  • As I mentioned, it's a closure... Mind you, I haven't implemented encode(to:) yet, which may make the problem more obvious! Ha!... I think I'm going to have to just manually set these closures after my container.decode(from:) calls. Should be fine, since they're basically hardwired anyway. – jbm Aug 31 '17 at 00:01
  • 1
    By the way, the class does ensure that E is Codable. The problem is that there's no overload that takes a closure as an argument... which is understandable, as it isn't obvious how a closure would be serialized, and it probably wouldn't be a good idea (security wise) anyway... – jbm Aug 31 '17 at 23:15

1 Answers1

2

You can use a trick to solve that:

typealias YourCompletion = (_ status: Bool) -> Void
class Completion: Codable {
    var completion: YourCompletion?
    private enum CodingKeys: CodingKey {}
}
Rohit Sisodia
  • 895
  • 12
  • 13