使用 Xcode 和 Swift 将嵌套字典保存到 UserDefaults

Saving nested dictionary into UserDefaults using Xcode and Swift

我正在尝试在 userDefaults 中保存嵌套字典。 当我尝试以通常的方式保存应用程序时,应用程序崩溃了,即

defaults.set(totalBuy, forKey: "test")

我得到这个错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object

当我尝试将它转换为 NSData 然后尝试检索它时,它总是返回 nil。

代码如下:

var buyData = [Int : String]()
var buyingTotal = [String : [Int: String]]()
var totalBuy = [Int : [String : [Int: String]]]()


let buyerDict = defaults.dictionary(forKey: "buyerDict")
let test = defaults.dictionary(forKey: "test")
func userDefaultSave(){

    buyData[0] = value
    buyData[1] = value
    buyData[2] = value
    buyData[3] = value
    
    buyingTotal["skuu"] = buyData
    totalBuy[0] = buyingTotal
    
    let data: Data = NSKeyedArchiver.archivedData(withRootObject: totalBuy) /// converts to NS Data
    defaults.set(data, forKey: "buyerDict")

    defaults.set(totalBuy, forKey: "test")
    if let dic = defaults.dictionary(forKey: "test") as? [Int : [String : [Int: String]]]  {
        print(dic)
    }

    let retrieved = defaults.object(forKey: "buyerDict") as! Data
    let dictionary: Dictionary? = NSKeyedUnarchiver.unarchiveObject(with: retrieved) as? [String : Any]
    
    print("dictionary--->", dictionary as Any)
}

谁能帮帮我?

您的字典需要将键 Int 更改为 String 或者将字典转换为数据并检索它。

尝试使用此方法从 userdefault 设置和获取您的值

let USERDEFAULT = UserDefaults.standard

class func setUserValueArchiver(value:Any, key :String) -> Void{
    guard !(value is NSNull) else {
        return
    }
    do{
        let archive = try NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true)
        USERDEFAULT.set(archive, forKey: key)
        USERDEFAULT.synchronize()
    }catch let error{
        Log("Error Save in UserDefault \(error.localizedDescription)")
    }
}

class func getUserUnArchiveData(key : String) -> Any?{
    if let userdata = USERDEFAULT.object(forKey: key) as? Data{
        do{
            let unarchived = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(userdata)
            return unarchived
        }catch let error{
            Log("Error At Get UserDATA :\(error.localizedDescription)")
        }
    }
    return nil
}

有两种方法可以使它正常工作。

1.可以使用JSONEncoder()JSONDecoder()Dictionary 对象获取 data,即

要从 totalBuy 获取 data

if let data = try? JSONEncoder().encode(totalBuy) {
    defaults.set(data, forKey: "buyerDict")
}

要从 data 获取 Dictionary

if let data = defaults.data(forKey: "buyerDict"), let dict = try? JSONDecoder().decode([Int:[String:[Int:String]]].self, from: data) {
    print(dict)
}

2. 如果您仍然想使用 NSKeyedArchiverNSKeyedArchiver ,给你

要从 totalBuy 获取 data

let data = try? NSKeyedArchiver.archivedData(withRootObject: totalBuy)
defaults.set(data, forKey: "buyerDict")

要从 data 获取 Dictionary

if let data = defaults.data(forKey: "buyerDict") {
    let dict = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
    print(dict)
}

UserDefaults.

检索 data 时使用 data(forKey:) 而不是 object(forKey:)