I'm trying to encode/decode some classes with subclasses, switching from NSCoder to Codable. The encoding looks like it works, but decoding a custom class with subclasses doesn't seem to work at all. It does not throw an error, but it also never calls any of the decoder initializers. It's probably something I'm doing wrong, but does anyone know of any pitfalls with this, a common reason why it might not be working?
Codable custom class decoder not called
You're going to have to break down the scenario a bit more. What kind of encoder/decoder are you using? (JSON, property list, keyed archiver/unarchiver?) How are you expecting to recognized which subclass to create at any point in the decoding? (Codable doesn't store class names for Swift classes, so it may not know which subclass to create, if the object you encoded could be any of several different subclasses.)
Also, Codable currently has a major flaw when used with NSKeyedArchiver — objects get archived as many times as they are referenced, rather than once per object (as NSCoding provides). This means that, if your data has cross-references between between objects, Codable simply won't work.
You might be better off sticking with NSCoding for now, at least for 'class' objects in Swift.
Thanks for the reply. Right now I am using property list, though I didn't know it mattered. Also I didn't realize that Codable didn't store class information -- all the Codable documentation I've seen so far steers clear of talking about inheritance.
So right now I have a class 'Node', which is a subclass of another class. In my top-level decoder function, I've got something like this:
rootNode = try container.decode(Node.self, forKey: .root)Now, I'm telling it to decode a Node, so I don't see why it would not call Node's 'decode' function. But it doesn't seem to. Stepping through the debugger, it just steps over this call. However, it does throw an error:
keyNotFound(App.transformCoder.TransformCodingKeys.rotmatrix, Swift.DecodingError.Context(codingPath: [App.Filer.FilerCodingKeys.root], debugDescription: "No value associated with key rotmatrix (\"rotmatrix\").", underlyingError: nil))This 'transformCoder' class is the root class of Node. So it does seem like it's trying -- but I've got debugger breakpoints in the decode functions at every level of the class heirarchy, and it isn't hitting them. So I don't know what is going on.
So, Node implements Decodable explicitly, not relying on synthesis? No synthesis for Encodable either?
If you've written it all explicitly, then it looks like you've got something wrong with your 'super'/'superDecoder'/'superEncoder' calls. Is it possible to show the "init(from:)" and "encode{to:)" methods of Node, or at least enough of them for use to be able form a picture of what's going on?
Thanks -- yes there was something wrong with the superclass decoder. It was just confusing because for some reason XCode wasn't stopping at any breakpoints in those functions. It is behaving correctly now though. I think I can get it to work -- now ust need to deal with the fact that the decoder doesn't know about subclass types.