SwiftyJD
SwiftyJD

Reputation: 5461

'self' used before self.init call error while using NSCoding on a custom class

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.

Upvotes: 0

Views: 1748

Answers (3)

Jake S
Jake S

Reputation: 1

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

}

Upvotes: 0

OOPer
OOPer

Reputation: 47906

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()
}

Upvotes: 1

Phillip Mills
Phillip Mills

Reputation: 31026

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.

Upvotes: 0

Related Questions