Attempt to set a non-property-list object as an NSUserDefaults

前端 未结 11 1716
闹比i
闹比i 2020-11-22 15:00

I thought I knew what was causing this error, but I can\'t seem to figure out what I did wrong.

Here is the full error message I am getting:

Attempt to se         


        
11条回答
  •  無奈伤痛
    2020-11-22 15:35

    It seems rather wasteful to me to run through the array and encode the objects into NSData yourself. Your error BC_Person is a non-property-list object is telling you that the framework doesn't know how to serialize your person object.

    So all that is needed is to ensure that your person object conforms to NSCoding then you can simply convert your array of custom objects into NSData and store that to defaults. Heres a playground:

    Edit: Writing to NSUserDefaults is broken on Xcode 7 so the playground will archive to data and back and print an output. The UserDefaults step is included in case its fixed at a later point

    //: Playground - noun: a place where people can play
    
    import Foundation
    
    class Person: NSObject, NSCoding {
        let surname: String
        let firstname: String
    
        required init(firstname:String, surname:String) {
            self.firstname = firstname
            self.surname = surname
            super.init()
        }
    
        //MARK: - NSCoding -
        required init(coder aDecoder: NSCoder) {
            surname = aDecoder.decodeObjectForKey("surname") as! String
            firstname = aDecoder.decodeObjectForKey("firstname") as! String
        }
    
        func encodeWithCoder(aCoder: NSCoder) {
            aCoder.encodeObject(firstname, forKey: "firstname")
            aCoder.encodeObject(surname, forKey: "surname")
        }
    }
    
    //: ### Now lets define a function to convert our array to NSData
    
    func archivePeople(people:[Person]) -> NSData {
        let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(people as NSArray)
        return archivedObject
    }
    
    //: ### Create some people
    
    let people = [Person(firstname: "johnny", surname:"appleseed"),Person(firstname: "peter", surname: "mill")]
    
    //: ### Archive our people to NSData
    
    let peopleData = archivePeople(people)
    
    if let unarchivedPeople = NSKeyedUnarchiver.unarchiveObjectWithData(peopleData) as? [Person] {
        for person in unarchivedPeople {
            print("\(person.firstname), you have been unarchived")
        }
    } else {
        print("Failed to unarchive people")
    }
    
    //: ### Lets try use NSUserDefaults
    let UserDefaultsPeopleKey = "peoplekey"
    func savePeople(people:[Person]) {
        let archivedObject = archivePeople(people)
        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setObject(archivedObject, forKey: UserDefaultsPeopleKey)
        defaults.synchronize()
    }
    
    func retrievePeople() -> [Person]? {
        if let unarchivedObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsPeopleKey) as? NSData {
            return NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject) as? [Person]
        }
        return nil
    }
    
    if let retrievedPeople = retrievePeople() {
        for person in retrievedPeople {
            print("\(person.firstname), you have been unarchived")
        }
    } else {
        print("Writing to UserDefaults is still broken in playgrounds")
    }
    

    And Voila, you have stored an array of custom objects into NSUserDefaults

提交回复
热议问题