问题描述
我在Playground中使用Swift 3,Xcode 8.0:
I have this in Playground using 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")
}
}
创建人员数组
create array of Person
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
编码数组
encode the array
let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)
print("encodedData: \(encodedData))")
保存为userDefaults
save to userDefaults
let userDefaults: UserDefaults = UserDefaults.standard()
userDefaults.set(encodedData, forKey: "people")
userDefaults.synchronize()
检查
check
print("saved object: \(userDefaults.object(forKey: "people"))")
从userDefaults撤消
retreive from 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")
}
只需检查已存档的数据
just check the archived data
if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){
print("myPeopleList: \(myPeopleList)")
}else{
print("There is an issue")
}
我无法正确地将数据对象保存为userDefaults,此外,底部的检查还会产生错误严重错误:在解开Optional值时意外发现nil". 检查"行还显示已保存的对象为nil.这是我对象的NSCoder中的错误吗?
I'm not able to correctly save the data object to userDefaults, and in addition, the check at the bottom creates the error "fatal error: unexpectedly found nil while unwrapping an Optional value". The "check" line also shows the saved object is nil. Is this an error in my object's NSCoder?
推荐答案
Swift 4或更高版本
您可以再次在Playground中保存/测试您的值
You can once again save/test your values in a Playground
UserDefaults需要在真实项目中进行测试.注意:无需强制同步.如果要在运动场中测试编码/解码,则可以使用键控存档器将数据保存到文档目录中的plist文件中.您还需要修复班级中的一些问题:
UserDefaults need to be tested in a real project. Note: No need to force synchronize. If you want to test the coding/decoding in a playground you can save the data to a plist file in the document directory using the keyed archiver. You need also to fix some issues in your class:
class Person: NSObject, NSCoding {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
required init(coder decoder: NSCoder) {
self.name = decoder.decodeObject(forKey: "name") as? String ?? ""
self.age = decoder.decodeInteger(forKey: "age")
}
func encode(with coder: NSCoder) {
coder.encode(name, forKey: "name")
coder.encode(age, forKey: "age")
}
}
测试:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// setting a value for a key
do {
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
let encodedData = try NSKeyedArchiver.archivedData(withRootObject: people, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "people")
} catch {
print(error)
}
// retrieving a value for a key
do {
if let data = UserDefaults.standard.data(forKey: "people"),
let myPeopleList = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Person] {
myPeopleList.forEach({print( $0.name, $0.age)}) // Joe 10
} else {
print("There is an issue")
}
} catch {
print(error)
}
}
}
这篇关于Swift 3从userDefaults保存和检索自定义对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!