1

I have an init method to init my model with JSON data, however when I want to also store this object in NSUserDefaults ill need to create acoder and adecoder init methods.

Im getting the error:

Cannot invoke 'UserProfileModel.init' with an argument list of type '(apiKey: String, userID: String, userEmail: String, lastName: String, firstName: String, company: String, userImage: String, jobTitle: String)'

the init for aDecoder is:

required convenience init(coder aDecoder: NSCoder) {
    let apiKey = aDecoder.decodeObject(forKey: "apiKey") as! String
    let userID = aDecoder.decodeObject(forKey: "userID") as! String
    let userEmail = aDecoder.decodeObject(forKey: "userEmail") as! String
    let lastName = aDecoder.decodeObject(forKey: "lastName") as! String
    let firstName = aDecoder.decodeObject(forKey: "firstName") as! String
    let company = aDecoder.decodeObject(forKey: "company") as! String
    let userImage = aDecoder.decodeObject(forKey: "userImage") as! String
    let jobTitle = aDecoder.decodeObject(forKey: "jobTitle") as! String
    self.init(apiKey: apiKey, userID: userID, userEmail: userEmail, lastName: lastName, firstName: firstName, company: company, userImage: userImage, jobTitle: jobTitle)
}

but I already have this init:

 init?(_ json: JSON) {
    // Map API Key from top level
    guard let apiKey = json["apikey"].string
    else { return nil }

    // assign user
    guard let userID = json["user"]["id"].string,
          let userEmail = json["user"]["email"].string,
          let lastName = json["user"]["lastname"].string,
          let firstName = json["user"]["firstname"].string
    else { return nil }

    // assign optionals to user
    let company = json["user"]["company"].string
    let userImage = json["user"]["image"].string
    let jobTitle = json["user"]["jobtitle"].string

    // Assign to model properties
    self.apiKey = apiKey
    self.userID = userID
    self.userEmail = userEmail
    self.lastName = lastName
    self.firstName = firstName
    self.company = company
    self.userImage = userImage
    self.jobTitle = jobTitle
}

How do reconcile both to work without throwing this error?

jackdm
  • 319
  • 7
  • 17

1 Answers1

1

Make your decoder function a required init and not convenience init.

required init(coder aDecoder: NSCoder) {
    self.apiKey = aDecoder.decodeObject(forKey: "apiKey") as! String
    self.userID = aDecoder.decodeObject(forKey: "userID") as! String
    self.userEmail = aDecoder.decodeObject(forKey: "userEmail") as! String
    self.lastName = aDecoder.decodeObject(forKey: "lastName") as! String
    self.firstName = aDecoder.decodeObject(forKey: "firstName") as! String
    self.company = aDecoder.decodeObject(forKey: "company") as! String
    self.userImage = aDecoder.decodeObject(forKey: "userImage") as! String
    self.jobTitle = aDecoder.decodeObject(forKey: "jobTitle") as! String
}

Thats all :) Hope it helps

What is the issue ?

In iOS all convenience init should ultimately call designated initializer. In your case you already have a designated initializer which accepts jSON. Now two solutions.

One declare a designated init which takes all the values like the one you used in last line of init(coder aDecoder: NSCoder) of your code and make your init(_ json: JSON) also a convenience initializer and finally in both init(coder aDecoder: NSCoder) and init(_ json: JSON) call designated initializer

else simply use the second and easy approach I specified above.

EDIT:

if i make it required, how am i doing to init with JSON ? ill need to do this too?

Yes you need to write required init(coder aDecoder: NSCoder) { because you are confirming to NSCoding protocol and NSCoding protocol expects you to implement this init. Hence its a required init.

where as your init(_ json: JSON) { is a designated initializer of your class.

Whats the difference between designated initializer and required initializer ?

Please read : What's the difference between a required initializer and a designated initializer?

As it clearly concludes

  • Required initialisers don't have to be designated.
  • Designated initialisers don't have to be required.
Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78