To use NSCoding with Swift's Enum type I made an extension on NSCoder:
extension NSCoder {
func encodeEnum<Enum: RawRepresentable where Enum.RawValue == String>(value: Enum, forKey key: String) {
self.encodeObject(value.rawValue, forKey: key)
}
func decodeEnumForKey<Enum: RawRepresentable where Enum.RawValue == String>(key: String) -> Enum? {
guard let returnValue = self.decodeObjectForKey(key) as? String else { return nil }
return Enum(rawValue: returnValue)
}
}
The encodeEnum method works fine for a String-backed Enum, but when I try to decode the prior encoded Enum like so:
enum MyEnum: String { case Something, Other }
class MyEnumClass: NSObject, NSCoding {
let myEnum: MyEnum
init(myEnum: MyEnum) {
self.myEnum = myEnum
}
required convenience init?(coder aDecoder: NSCoder) {
guard let tmp = aDecoder.decodeEnumForKey("myKey") as? MyEnum else { return nil }
self.init(myEnum: tmp)
}
}
I get an error on aDecoder.decodeEnumForKey("myKey"):
Value of type `NSCoder` has no member `RawValue`
I'm pretty sure it has something to do with the generic and the condition that Enum.RawValue == String. But I do not understand while it's not working, but works for encodeEnum().
The problem is that in
the compiler cannot infer the generic placeholder of
to be
MyEnum, you have to cast the result toMyEnum?instead:so that the return type is inferred as
MyEnum?from the calling context.