Swift 3从userDefaults保存和检索自定义对象

我在Playground中使用Swift 3,Xcode 8.0拥有此功能:


import Foundation

class Person: NSObject, NSCoding {

    var name: String

    var age: Int

    init(name: String, age: Int) {

        self.name = name

        self.age = age

    }

    required convenience init(coder aDecoder: NSCoder) {

        let name = aDecoder.decodeObject(forKey: "name") as! String

        let age = aDecoder.decodeObject(forKey: "age") as! Int

        self.init(

            name: name,

            age: age

        )

    }

    func encode(with aCoder: NSCoder) {

        aCoder.encode(name, forKey: "name")

        aCoder.encode(age, forKey: "age")

    }

}

创建人员数组


let newPerson = Person(name: "Joe", age: 10)

var people = [Person]()

people.append(newPerson)

编码数组


let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)

print("encodedData: \(encodedData))")

保存到用户默认值


let userDefaults: UserDefaults = UserDefaults.standard()

userDefaults.set(encodedData, forKey: "people")

userDefaults.synchronize()

校验


print("saved object: \(userDefaults.object(forKey: "people"))")

从userDefaults返回


if let data = userDefaults.object(forKey: "people") {

    let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data as! Data)

    print("myPeopleList: \(myPeopleList)")

}else{

    print("There is an issue")

}

只需检查存档的数据


if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){

   print("myPeopleList: \(myPeopleList)")

}else{

   print("There is an issue")

}

我无法正确将数据对象保存到userDefaults,此外,底部的检查还会产生错误“严重错误:在展开可选值时意外发现nil”。“检查”行还显示已保存的对象为nil。这是我对象的NSCoder中的错误吗?


潇潇雨雨
浏览 825回答 3
3回答

慕妹3242003

let age = aDecoder.decodeObject(forKey: "age") as! IntSwift 3对此进行了更改;这不再适用于值类型。现在正确的语法是:let age = aDecoder.decodeInteger(forKey: "age")有针对各种不同类型的关联的encode ...()函数:let myBool = aDecoder.decodeBoolean(forKey: "myStoredBool")let myFloat = aDecoder.decodeFloat(forKey: "myStoredFloat")编辑:Swift 3中所有可能的encodeXXX函数的完整列表编辑:另一个重要的注意事项:如果您以前保存过使用较早版本的Swift编码的数据,则必须使用encodeObject()解码这些值,但是一旦使用encode(...)重新编码数据,就不能再使用如果它是值类型,则使用decodeObject()解码。因此,Markus Wyss的答案将允许您处理使用两种Swift版本对数据进行编码的情况:self.age = aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")
打开App,查看更多内容
随时随地看视频慕课网APP