Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 保存并加载自定义词典-NSUserDefaults_Ios_Swift_Dictionary_Nsuserdefaults - Fatal编程技术网

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

Ios 保存并加载自定义词典-NSUserDefaults,ios,swift,dictionary,nsuserdefaults,Ios,Swift,Dictionary,Nsuserdefaults,我有一本[Int:Bool]字典,我正试图将它保存到我的NSDictionary中。。但是,如果试图设置非属性列表对象,则会出现错误而崩溃 let dictionary = [Int:Bool]() self.dictionary[2] = true self.dictionary[3] = false NSUserDefaults.standardUserDefaults().setObject(dictionary, forKey: "dictionary") 另外,对于加载,首先

我有一本
[Int:Bool]
字典,我正试图将它保存到我的NSDictionary中。。但是,如果试图设置非属性列表对象,则会出现错误
而崩溃

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]
我还尝试了
字典工作
。我得到了

NSUserDefaults.standardUserDefaults().dictionaryForKey("dictionary")
无法将类型[String:AnyObject]的值赋给类型[Int:Bool]


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

斯威夫特4 在基本类型中,
UserDefaults
可以保存符合
Codable
协议的任何对象<代码>字典
是实现此协议的类型之一。您甚至不需要编写任何自定义代码:

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]
查看有关的更多信息

斯威夫特3 只要键和值类型是可以用plist格式表示的类型(
NSNumber
数据
等),就可以使用
UserDefaults
保存
字典。如果不是这样,我们可以在写入时将其他类型序列化为
数据
,在读取时从
数据
反序列化。可以使用
NSKeyArchiver
UserDefaults
进行非常简单的扩展:

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]
    }
}
斯威夫特2 保存自定义数据

检索数据

用法


我也有类似的问题,但数据类型不同。 我的建议是转换为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)
}

保存后是否同步了NSUserDefault
NSUserDefaults.standardUserDefaults().synchronize()
我认为您应该使用
DictionaryWorkery(:)
.Ahh。我完全忘了把它添加到问题中。我也试过。。正在获取错误。。更新了我的问题:如果在当前范围内声明,为什么要使用
self访问
词典
此外,显然不能向使用
let
声明的词典添加值……不是
类型的东西[Int:Bool]
自动转换为
NSDictionary
?否。这是因为Swift dictionary是泛型结构
dictionary
,而
NSDictionary
是ObjectiveC
NSObject
派生类。它们在早期版本的Swift中被桥接,但现在没有。你能用一个来源来备份吗?这对我来说在操场上很有用:
let dictionary:NSDictionary=[1:“a”,2:“b”]
@TimVermeulen似乎
NSDictionary
仍然与swift
dictionary
保持着联系。类型之间的转换不会自动进行,您可以使用swift字典语法初始化
NSDictionary
。但这也可以起作用:
let dict=[1:“a”,2:“b”];让nsDict:NSDictionary=dict
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()
/// 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]
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)
}
    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)