使用 UserDefaults 在 Swift 中保存自定义对象的字典
Save Dictionary of custom objects in Swift using UserDefaults
我正在编写一个应用程序来处理联系人并尝试使用 UserDefaults 保存信息,但我收到了 SIGABRT。这是我的代码,我做错了什么?
class Contact{
var name = String()
var phone = String()
init(name: String, phone: String){
self.name=name
self.phone=phone
}
required init(coder decoder: NSCoder){
self.name = (decoder.decodeObject(forKey: "name") as? String)!
self.phone = (decoder.decodeObject(forKey: "phone") as? String)!
}
func encode(with coder: NSCoder){
coder.encode(name, forKey: "name")
coder.encode(phone, forKey: "phone")
}
}
正在 ViewDidLoad 中创建联系人以进行测试:
let userDefaults = UserDefaults.standard
var contactDictionary = Dictionary<String, [Contact]>()
override func viewDidLoad() {
super.viewDidLoad()
contactDictionary["A"] = [Contact(name: "Annabel",phone: "000")]
let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
userDefaults.set(encodedData, forKey: "contactDictionary")
userDefaults.synchronize()
if let data = userDefaults.data(forKey: "contactDictionary"){
print("yep")
contactDictionary = (NSKeyedUnarchiver.unarchiveObject(with: data) as? [String : [Contact]])!
}
else{
print("nope")
}
}
您需要使您的 class NSCoding 兼容并继承自 NSObject。将您的联系人声明更改为 class Contact: NSObject, NSCoding {.顺便说一句,有条件地强制强制解开它是没有意义的。 decoder.decodeObject(forKey: "name") as! String
class Contact: NSObject, NSCoding {
var name = String()
var phone = String()
init(name: String, phone: String){
self.name=name
self.phone=phone
}
required init(coder decoder: NSCoder){
self.name = decoder.decodeObject(forKey: "name") as! String
self.phone = decoder.decodeObject(forKey: "phone") as! String
}
func encode(with coder: NSCoder){
coder.encode(name, forKey: "name")
coder.encode(phone, forKey: "phone")
}
}
测试:
let contactDictionary = ["A":[Contact(name: "Annabel",phone: "000")]]
let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
UserDefaults.standard.set(encodedData, forKey: "contactDictionary")
if let data = UserDefaults.standard.data(forKey: "contactDictionary") {
print("yep")
let contactDictionary2 = NSKeyedUnarchiver.unarchiveObject(with: data) as! [String : [Contact]]
}
else{
print("nope")
}
我正在编写一个应用程序来处理联系人并尝试使用 UserDefaults 保存信息,但我收到了 SIGABRT。这是我的代码,我做错了什么?
class Contact{
var name = String()
var phone = String()
init(name: String, phone: String){
self.name=name
self.phone=phone
}
required init(coder decoder: NSCoder){
self.name = (decoder.decodeObject(forKey: "name") as? String)!
self.phone = (decoder.decodeObject(forKey: "phone") as? String)!
}
func encode(with coder: NSCoder){
coder.encode(name, forKey: "name")
coder.encode(phone, forKey: "phone")
}
}
正在 ViewDidLoad 中创建联系人以进行测试:
let userDefaults = UserDefaults.standard
var contactDictionary = Dictionary<String, [Contact]>()
override func viewDidLoad() {
super.viewDidLoad()
contactDictionary["A"] = [Contact(name: "Annabel",phone: "000")]
let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
userDefaults.set(encodedData, forKey: "contactDictionary")
userDefaults.synchronize()
if let data = userDefaults.data(forKey: "contactDictionary"){
print("yep")
contactDictionary = (NSKeyedUnarchiver.unarchiveObject(with: data) as? [String : [Contact]])!
}
else{
print("nope")
}
}
您需要使您的 class NSCoding 兼容并继承自 NSObject。将您的联系人声明更改为 class Contact: NSObject, NSCoding {.顺便说一句,有条件地强制强制解开它是没有意义的。 decoder.decodeObject(forKey: "name") as! String
class Contact: NSObject, NSCoding {
var name = String()
var phone = String()
init(name: String, phone: String){
self.name=name
self.phone=phone
}
required init(coder decoder: NSCoder){
self.name = decoder.decodeObject(forKey: "name") as! String
self.phone = decoder.decodeObject(forKey: "phone") as! String
}
func encode(with coder: NSCoder){
coder.encode(name, forKey: "name")
coder.encode(phone, forKey: "phone")
}
}
测试:
let contactDictionary = ["A":[Contact(name: "Annabel",phone: "000")]]
let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
UserDefaults.standard.set(encodedData, forKey: "contactDictionary")
if let data = UserDefaults.standard.data(forKey: "contactDictionary") {
print("yep")
let contactDictionary2 = NSKeyedUnarchiver.unarchiveObject(with: data) as! [String : [Contact]]
}
else{
print("nope")
}