使用编码器vs从Json处理Object init?

时间:2017-08-31 08:52:40

标签: ios swift nsuserdefaults

我有一个init方法来使用JSON数据初始化我的模型,但是当我想在NSUserDefaults中存储这个对象时,需要创建acoder和adecoder init方法。

我得到错误:

  

无法调用' UserProfileModel.init'使用类型'的参数列表(apiKey:String,userID:String,userEmail:String,lastName:String,firstName:String,company:String,userImage:String,jobTitle:String)'

aDecoder的init是:

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

但我已经有了这个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
}

如何在不抛出此错误的情况下协调工作?

1 个答案:

答案 0 :(得分:1)

使您的解码器功能成为必需的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
}

多数民众赞成:)希望有所帮助

有什么问题?

在iOS中,所有的方便init最终都应该调用指定的初始化程序。在您的情况下,您已经有一个接受jSON的指定初始化程序。现在有两个解决方案。

一个声明一个指定的init,它接受你在代码的init(coder aDecoder: NSCoder)的最后一行中使用的所有值,并使init(_ json: JSON)也成为一个便利初始化器,最后在init(coder aDecoder: NSCoder)中}和init(_ json: JSON)调用指定的初始化程序

否则只需使用我在上面指定的第二种简单方法。

修改

如果我需要它,我如何使用JSON进行初始化?我也不需要这样做吗?

是的,您需要编写required init(coder aDecoder: NSCoder) {,因为您正在确认NSCoding协议,NSCoding协议希望您实现此init。因此它是一个必需的init。

其中init(_ json: JSON) {是您班级的指定初始值设定项。

指定的初始化程序和所需的初始值设定项之间的区别是什么?

请阅读:What's the difference between a required initializer and a designated initializer?

明确总结

  • 不必指定所需的初始订阅者。
  • 不需要指定的初始订阅者。