0

I have some subclass of NSObject that defines a string representable Enum within in at follows:

class SomeClass: NSObject {

    enum Direction: String {
        case north = "North"
        case south = "South"
    }

    public var direction: Direction

    init(direction: Direction) {
        self.direction = direction
        super.init()
    }

}

I want to allow this class to be encoded and decoded, so I use the following:

func encode(with aCoder: NSCoder) {
    aCoder.encode(direction, forKey: #keyPath(direction))
}

public convenience required init?(coder aDecoder: NSCoder) {
    self.init(direction: aDecoder.decodeObject(forKey: #keyPath(direction)) as! Direction)
}

However, I get the following error Argument of '#keyPath' refers to non-'@objc' property 'direction' and when I change the definition of direction to

@objc public var direction: Direction

I get the error Property cannot be marked @objc because its type cannot be represented in Objective-C.

What's the best way to avoid this error, please?

Thanks for any help.

EDIT

The comments explain the problem. This answers in this link suggest how to accomplish using a String raw representable.

How to make a Swift String enum available in Objective-C?

ajrlewis
  • 2,968
  • 3
  • 33
  • 67
  • 1
    Try mark your `enum Direction` with `@objc` – Tj3n Jul 30 '18 at 10:20
  • @Tj3n Thanks ... I now get the following **'@objc' enum raw type 'String' is not an integer type** – ajrlewis Jul 30 '18 at 10:26
  • 2
    In objc there's no enum with String, you have to use Int enum and another function/computed variable to convert it to string – Tj3n Jul 30 '18 at 10:30

1 Answers1

2

You can take advantage of the rawValue support that String based enums (and not only) have:

func encode(with aCoder: NSCoder) {
    aCoder.encode(direction.rawValue, forKey: "direction")
}

public convenience required init?(coder aDecoder: NSCoder) {
    guard let direction = Direction(rawValue: aDecoder.decodeObject(forKey: "direction") else {
        // direction was not encoded, we assume an encoding error
        return nil
    }
    self.init(direction: direction)
}
Cristik
  • 30,989
  • 25
  • 91
  • 127