Encoding class with nested enum?

First, let me say I am actually still on the swift book not the iOS programming book but I bought the iOS book just for this chapter for a project I’m working on. So please keep in mind I’m a little behind you all in my skills.

I have a class called DreamSign that has two properties: name and dreaminess. dreaminess is of type Dreaminess which is an enum. I’m not sure how to go about encoding it with NSCoding, I’m just getting errors up the wazoo when I add any encoding code so I’m just going to post it without it.

  class DreamSign {
        var name = "Default Dream Sign"
        var dreaminess = Dreaminess.neutral
        
        enum Dreaminess: Int {
            case neutral    = 9 
            case somewhatLikely = 30 
            case likely     = 50 
            case veryLikely = 90 
            case definetly   = 99 
        }
        
        init(name: String, dreaminess: Dreaminess){
        self.name = name
        self.dreaminess = dreaminess
        }
    }

I was able to implement NSCoding with this class. Have you tried the following things?

  • Have DreamSign subclass NSObject.
  • Encode the dreaminess property as an Integer (using .rawValue), and upon decoding it, passing the unarchived rawValue when reinitializing dreaminess.

I also provide a coded solution below.

Spoiler Alert: Implementation
class DreamSign: NSObject, NSCoding {
  var name = "Default Dream Sign"
  var dreaminess = Dreaminess.neutral

  enum Dreaminess: Int {
    case neutral    = 9 
    case somewhatLikely = 30 
    case likely     = 50 
    case veryLikely = 90 
    case definetly   = 99 
  }

  init(name: String, dreaminess: Dreaminess) {
    self.name = name
    self.dreaminess = dreaminess

    // NOTE: Add this call now that this class is a subclass of NSObject.
    super.init()
  }

  // MARK: - NSCoding

  required init?(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    dreaminess = Dreaminess(rawValue: aDecoder.decodeInteger(forKey: "dreaminess"))!
    
    super.init()
  }

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

}