简体   繁体   中英

Saving Realm Object subclass in NSUserDefaults?

I'm introducing Realm into my swift project. I have a User class that I was saving an instance of into NSUserDefaults to keep track of the 1 logged in user.

After making User a subclass of Object, I get the following error when trying to unarchive (archiving seems to work OK):

Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (RLMStandalone_User) for key (root); the class may be defined in source code or a library that is not linked'

I have Realm installed as a Cocoapod, this are the relevant methods in the 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")
    }


}

It's not possible to store a Realm Object in NSUserDefaults as (As you saw in that error message) they cannot be serialized or deserialized by the NSCoding protocol.

Instead, it might be better to add a primary key property to your User object (So you can use it to query that exact object from Realm), and store the primary key itself in NSUserDefaults instead.

Or better yet, instead of relying on NSUSerDefaults , it might be better to simply have a boolean property, isCurrent in your model, and using that to work out which user is the current one.

You should keep your NSUserDefaults and your Realm data separate. They are two different methods of persistent data storage. If you've converted something to a Realm Object, you no longer need to (or should) try and put that into NSUserDefaults.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM