0

I'm trying to encode a custom class so I can save it using NSKeyedArchiver.archivedDataWithRootObject

but when I try to conform to the NSCoding protocol, I get this error : 'self' used before self.init. Here is my code:

class MemberRewardsInfo: NSObject, NSCoding {
var id: Int?


  required convenience init?(coder aDecoder: NSCoder) {

    guard let unarchivedId = aDecoder.decodeObjectForKey("id") as? Int

      else {
        return nil
      } 
  }


  func encodeWithCoder(aCoder: NSCoder) {

    aCoder.encodeObject(id, forKey: "id")
  }
}

its pretty annoying, not sure why it's not working.

SwiftyJD
  • 5,257
  • 7
  • 41
  • 92

3 Answers3

1

The error message is sort of misleading, but you need to make init(coder:) a designated initializer.

You need to modify your init(code:) to something like this:

required init?(coder aDecoder: NSCoder) {
    guard let unarchivedId = aDecoder.decodeObjectForKey("id") as? Int else {
            return nil
    }
    self.id = unarchivedId
    super.init()
}
Alexander
  • 59,041
  • 12
  • 98
  • 151
OOPer
  • 47,149
  • 6
  • 107
  • 142
0

Apparently it's upset about convenience. The assumption is that if you create a convenience initializer, it's going to chain to a "real initializer.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
0

When using a convenience initializer, just call the designated initializer, in your case, self.init(), inside block. See this example in Apple docs for an explanation.

required convenience init?(coder aDecoder: NSCoder) {
    guard let unarchivedId = aDecoder.decodeObjectForKey("id") as? Int

    else {
        return nil
    }
    self.init()
    self.id = unarchivedId

}

Jake S
  • 1
  • 1