保存并加载自定义词典 - NSUserDefaults

时间:2016-04-22 09:28:06

标签: ios swift 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")
  

无法为类型[String:AnyObject]指定值以键入[Int:Bool]

那么这两个中的哪一个是更好的方法? (我认为这些值在我的情况下是可选的)

1.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool] ?? [Int:Bool]()

2.
NSUserDefaults.standardUserDefaults().objectForKey("dictionary") as? [Int:Bool])!

4 个答案:

答案 0 :(得分:9)

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

只要键和值类型是可以plist格式(UserDefaultsDictionary等表示的类型,您就可以使用NSNumber保存Data )。如果情况并非如此,我们可以在阅读时从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()

答案 1 :(得分:0)

我有类似的问题,但有不同类型的数据。 我的建议是转换为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]]并且工作,所以也许它也适用于你!)

答案 2 :(得分:0)

这适用于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]
}

答案 3 :(得分:0)

如果你需要更多类型,你可以使用这样的泛型:

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)