在NSUserDefaults中保存Realm Object子类?

时间:2016-05-03 02:16:41

标签: ios xcode swift realm

我正在将Realm引入我的快速项目中。我有一个User类,我正在将一个实例保存到NSUserDefaults中以跟踪1个登录用户。

在将User作为Object的子类之后,在尝试取消归档时出现以下错误(归档似乎工作正常):

  

由于未捕获的异常而终止应用   ' NSInvalidUnarchiveOperationException',原因:' ***    - [NSKeyedUnarchiver decodeObjectForKey:]:无法解密类(RLMStandalone_User)对象的密钥(root);该类可以定义为   源代码或未链接的库

我将Realm作为Cocoapod安装,这是User clas中的相关方法

static var currentUser: User? {
    get {
        if let data = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultKeys.kUserData) as? NSData,
            let user = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? User {
            return user
        } else {
            return nil
        }
    }
    set {
        if let user = newValue {
            let data = NSKeyedArchiver.archivedDataWithRootObject(user)
            NSUserDefaults.standardUserDefaults().setObject(data, forKey: UserDefaultKeys.kUserData)
            NSUserDefaults.standardUserDefaults().synchronize()
        } else {
            NSUserDefaults.standardUserDefaults().removeObjectForKey(UserDefaultKeys.kUserData)
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }
}

// MARK: NSCoding

 convenience init?(coder decoder: NSCoder) {
    self.init()
    guard let firstName = decoder.decodeObjectForKey("firstName") as? String,
    let lastName = decoder.decodeObjectForKey("lastName") as? String,
    let email = decoder.decodeObjectForKey("email") as? String,
    let icloud = decoder.decodeObjectForKey("icloudUserID") as? String,
    let userType = decoder.decodeObjectForKey("userType") as? String
    else {
        return nil
    }

    self.firstName = firstName
    self.lastName = lastName
    self.email = email
    self.profilePic = decoder.decodeObjectForKey("profilePic") as? String
    self.icloudUserID = icloud
    self.userType = userType
    self.coverPhoto = decoder.decodeObjectForKey("coverPhoto") as? String
    self.facebookID = decoder.decodeObjectForKey("facebookID") as? String
    self.placeID = decoder.decodeObjectForKey("placeID") as? String
}

func encodeWithCoder(coder: NSCoder) {
    coder.encodeObject(self.firstName, forKey: "firstName")
    coder.encodeObject(self.lastName, forKey: "lastName")

    coder.encodeObject(self.icloudUserID, forKey: "icloudUserID")
    coder.encodeObject(self.userType, forKey: "userType")
    coder.encodeObject(email, forKey: "email")

    if let coverPhotoUrl = self.coverPhotoUrl {
        coder.encodeObject(coverPhotoUrl, forKey: "coverPhoto")
    }

    if let profilePicUrl = self.profilePicUrl {
        coder.encodeObject(profilePicUrl, forKey: "profilePic")
    }

    if let fbID = self.facebookID {
        coder.encodeObject(fbID, forKey: "facebookID")
    }

    if let placeID = self.placeID {
        coder.encodeObject(placeID, forKey: "placeID")
    }


}

2 个答案:

答案 0 :(得分:3)

无法在Object中存储领域NSUserDefaults(正如您在该错误消息中看到的那样),NSCoding协议无法对其进行序列化或反序列化。

相反,最好将一个主键属性添加到User对象(因此您可以使用它来从Realm查询该确切对象),并将主键本身存储在NSUserDefaults中代替。

或者更好的是,不是依赖于NSUSerDefaults,最好只在模型中使用布尔属性isCurrent,并使用它来确定哪个用户是当前用户。

答案 1 :(得分:1)

您应该将NSUserDefaults和Realm数据分开。它们是持久数据存储的两种不同方法。如果您已将某些内容转换为Realm对象,则不再需要(或应该)尝试将其转换为NSUserDefaults。