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.