保存和加载自定义字典 - NSUserDefaults
Save and Load Custom Dictionary - NSUserDefaults
我有一个 [Int:Bool]
字典,我正试图将它保存到我的 NSDictionary 中。但是,它因错误 Attempt to set a non-property-list object
而崩溃
let dictionary = [Int:Bool]()
self.dictionary[2] = true
self.dictionary[3] = false
NSUserDefaults.standardUserDefaults().setObject(dictionary, forKey: "dictionary")
此外,对于加载,我首先尝试了这个但错误记录它严格要求 AnyObject?。
NSUserDefaults.standardUserDefaults().objectForKey("dictionary")
然后我尝试了这个并记录了:
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool]
我也试过dictionaryForKey
。我得到了..
NSUserDefaults.standardUserDefaults().dictionaryForKey("dictionary")
Cannot assign value to type [String: AnyObject] to type [Int:Bool]
那么这两种方法中哪一种是更好的选择? (我认为这些值在我的情况下是可选的)
1.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool] ?? [Int:Bool]()
2.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool])!
Swift 4
基本类型中,UserDefaults
可以保存任何符合Codable
协议的对象。 Dictionary
是实现此协议的类型之一。您甚至不需要编写任何自定义代码:
let dictionary = ["name": "Adam"]
// Save to User Defaults
UserDefaults.standard.set(dictionary, forKey: "names")
// Read from User Defaults
let saved = UserDefaults.standard.value(forKey: "names") as? [String: String]
查看有关 Codable
的更多信息
Swift 3
你可以使用UserDefaults
来保存一个Dictionary
,只要键和值类型是可以用plist格式表示的类型(NSNumber
,Data
, ETC。)。如果不是这种情况,我们总是可以在写入时将其他类型序列化为 Data
,并在读取时从 Data
反序列化。它可以通过 UserDefaults
使用 NSKeyArchiver
:
的非常简单的扩展来完成
extension UserDefaults {
/// Save dictionary on key
open func set<Key, Value>(dictionary: [Key: Value]?, forKey key: String) {
let data = NSKeyedArchiver.archivedData(withRootObject: dictionary as Any)
set(data, forKey: key)
}
// Retrieve dictionary for key
open func dictionary<Key, Value>(forKey key: String) -> [Key: Value]? {
guard let data = object(forKey: key) as? Data else { return nil }
return NSKeyedUnarchiver.unarchiveObject(with: data) as? [Key: Value]
}
}
现在您可以调用这些方法:
let ages = ["Adam": 25]
// Save
UserDefaults.standard.set(dictionary: ages, forKey: "ages")
// Read
let saved: [String: Int]? = UserDefaults.standard.dictionary(forKey: "ages")
print(saved) // Optional(["Adam": 25])
Swift 2
保存自定义数据
func setCustomDictionary(dict: [Int: Bool]) {
let keyedArch = NSKeyedArchiver.archivedDataWithRootObject(dict)
NSUserDefaults.standardUserDefaults().setObject(keyedArch, forKey: "dictionary")
}
检索数据
func getDictionary() -> [Int: Bool]? {
let data = NSUserDefaults.standardUserDefaults().objectForKey("dict")
let object = NSKeyedUnarchiver.unarchiveObjectWithData(data as! NSData)
return object as? [Int: Bool]
}
用法
var customDictionary = [Int: Bool]()
customDictionary[2] = true
customDictionary[3] = false
// Store data in NSUserDefaults
setCustomDictionary(customDictionary)
// Get data from NSUserDefaults
let userDefaultsDictionary = getDictionary()
我遇到了类似的问题,但数据类型不同。
我的建议是转换为 NSData 并像这样检索数据:
/// Save
NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(object), forKey: key)
/// Read
var data = NSUserDefaults.standardUserDefaults().objectForKey(key) as NSData
var object = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [String: String]
(虽然提到 [String : String] 我实际上用于 [[String: AnyObject]] 并且有效,所以也许它也适用于你!)
这是给 Swift 3
func setCustomDictionary(dict: [Int: Bool]) {
let keyedArch = NSKeyedArchiver.archivedData(withRootObject: dict)
UserDefaults.standard.set(keyedArch, forKey: "dictionary")
}
func getDictionary() -> [Int: Bool]? {
let data = UserDefaults.standard.object(forKey: "dict")
let object = NSKeyedUnarchiver.unarchiveObject(with: (data as! NSData) as Data)
return object as? [Int: Bool]
}
如果您需要更多类型,您可以像这样使用泛型:
func saveUserDefaults<T>(withKey key: String, dict: AnyObject, myType: T.Type) {
guard let dict = dict as? T else {
print("Type mismatch")
return
}
let archiver = NSKeyedArchiver.archivedData(withRootObject: dict)
UserDefaults.standard.set(archiver, forKey: key)
}
func getUserDefaults<T>(withKey key: String, myType: T.Type) -> T? {
let unarchivedObject = getUserDefaultData(withKey: key)
return unarchivedObject as? T
}
func getUserDefaultData(withKey key: String) -> Any? {
guard let data = UserDefaults.standard.object(forKey: key) else {
return nil
}
guard let retrievedData = data as? Data else {
return nil
}
return NSKeyedUnarchiver.unarchiveObject(with: retrievedData)
}
例如[Int:Int]类型用法:
var customDictionary = [Int: Int]()
customDictionary[234] = 1
customDictionary[24] = 2
customDictionary[345] = 3
saveUserDefaults(withKey: "hello", dict: customDictionary as AnyObject, myType: [Int: Int].self)
let savedDictionary = getUserDefaults(withKey: "hello", myType: [Int: Int].self)
print(savedDictionary)
我有一个 [Int:Bool]
字典,我正试图将它保存到我的 NSDictionary 中。但是,它因错误 Attempt to set a non-property-list object
let dictionary = [Int:Bool]()
self.dictionary[2] = true
self.dictionary[3] = false
NSUserDefaults.standardUserDefaults().setObject(dictionary, forKey: "dictionary")
此外,对于加载,我首先尝试了这个但错误记录它严格要求 AnyObject?。
NSUserDefaults.standardUserDefaults().objectForKey("dictionary")
然后我尝试了这个并记录了:
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool]
我也试过dictionaryForKey
。我得到了..
NSUserDefaults.standardUserDefaults().dictionaryForKey("dictionary")
Cannot assign value to type [String: AnyObject] to type [Int:Bool]
那么这两种方法中哪一种是更好的选择? (我认为这些值在我的情况下是可选的)
1.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool] ?? [Int:Bool]()
2.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool])!
Swift 4
基本类型中,UserDefaults
可以保存任何符合Codable
协议的对象。 Dictionary
是实现此协议的类型之一。您甚至不需要编写任何自定义代码:
let dictionary = ["name": "Adam"]
// Save to User Defaults
UserDefaults.standard.set(dictionary, forKey: "names")
// Read from User Defaults
let saved = UserDefaults.standard.value(forKey: "names") as? [String: String]
查看有关 Codable
的更多信息Swift 3
你可以使用UserDefaults
来保存一个Dictionary
,只要键和值类型是可以用plist格式表示的类型(NSNumber
,Data
, ETC。)。如果不是这种情况,我们总是可以在写入时将其他类型序列化为 Data
,并在读取时从 Data
反序列化。它可以通过 UserDefaults
使用 NSKeyArchiver
:
extension UserDefaults {
/// Save dictionary on key
open func set<Key, Value>(dictionary: [Key: Value]?, forKey key: String) {
let data = NSKeyedArchiver.archivedData(withRootObject: dictionary as Any)
set(data, forKey: key)
}
// Retrieve dictionary for key
open func dictionary<Key, Value>(forKey key: String) -> [Key: Value]? {
guard let data = object(forKey: key) as? Data else { return nil }
return NSKeyedUnarchiver.unarchiveObject(with: data) as? [Key: Value]
}
}
现在您可以调用这些方法:
let ages = ["Adam": 25]
// Save
UserDefaults.standard.set(dictionary: ages, forKey: "ages")
// Read
let saved: [String: Int]? = UserDefaults.standard.dictionary(forKey: "ages")
print(saved) // Optional(["Adam": 25])
Swift 2
保存自定义数据
func setCustomDictionary(dict: [Int: Bool]) {
let keyedArch = NSKeyedArchiver.archivedDataWithRootObject(dict)
NSUserDefaults.standardUserDefaults().setObject(keyedArch, forKey: "dictionary")
}
检索数据
func getDictionary() -> [Int: Bool]? {
let data = NSUserDefaults.standardUserDefaults().objectForKey("dict")
let object = NSKeyedUnarchiver.unarchiveObjectWithData(data as! NSData)
return object as? [Int: Bool]
}
用法
var customDictionary = [Int: Bool]()
customDictionary[2] = true
customDictionary[3] = false
// Store data in NSUserDefaults
setCustomDictionary(customDictionary)
// Get data from NSUserDefaults
let userDefaultsDictionary = getDictionary()
我遇到了类似的问题,但数据类型不同。 我的建议是转换为 NSData 并像这样检索数据:
/// Save
NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(object), forKey: key)
/// Read
var data = NSUserDefaults.standardUserDefaults().objectForKey(key) as NSData
var object = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [String: String]
(虽然提到 [String : String] 我实际上用于 [[String: AnyObject]] 并且有效,所以也许它也适用于你!)
这是给 Swift 3
func setCustomDictionary(dict: [Int: Bool]) {
let keyedArch = NSKeyedArchiver.archivedData(withRootObject: dict)
UserDefaults.standard.set(keyedArch, forKey: "dictionary")
}
func getDictionary() -> [Int: Bool]? {
let data = UserDefaults.standard.object(forKey: "dict")
let object = NSKeyedUnarchiver.unarchiveObject(with: (data as! NSData) as Data)
return object as? [Int: Bool]
}
如果您需要更多类型,您可以像这样使用泛型:
func saveUserDefaults<T>(withKey key: String, dict: AnyObject, myType: T.Type) {
guard let dict = dict as? T else {
print("Type mismatch")
return
}
let archiver = NSKeyedArchiver.archivedData(withRootObject: dict)
UserDefaults.standard.set(archiver, forKey: key)
}
func getUserDefaults<T>(withKey key: String, myType: T.Type) -> T? {
let unarchivedObject = getUserDefaultData(withKey: key)
return unarchivedObject as? T
}
func getUserDefaultData(withKey key: String) -> Any? {
guard let data = UserDefaults.standard.object(forKey: key) else {
return nil
}
guard let retrievedData = data as? Data else {
return nil
}
return NSKeyedUnarchiver.unarchiveObject(with: retrievedData)
}
例如[Int:Int]类型用法:
var customDictionary = [Int: Int]()
customDictionary[234] = 1
customDictionary[24] = 2
customDictionary[345] = 3
saveUserDefaults(withKey: "hello", dict: customDictionary as AnyObject, myType: [Int: Int].self)
let savedDictionary = getUserDefaults(withKey: "hello", myType: [Int: Int].self)
print(savedDictionary)