Swift - 将字典数组保存到 NSUserDefaults

Posted

技术标签:

【中文标题】Swift - 将字典数组保存到 NSUserDefaults【英文标题】:Swift - Save Array of dictionaries into NSUserDefaults 【发布时间】:2015-06-15 20:20:10 【问题描述】:

我有一个空的购物车数组 -> var cart: [Dictionary<String, Any>] = []

我有 2 个屏幕,productsView 和 resumeView。进入产品视图,我有一些产品。当用户点击产品时,它会进入购物车:

cart = [[name: "A", price: "1", qty: "1"]]

如果用户点击更多产品:

cart = [[name: "A", price: "1", qty: "3"],[name: "B", price: "2", qty: "1"]]

现在,当用户完成将产品添加到购物车后,我想显示带有产品列表的第二个视图,用户可以更改产品“数量”或删除产品。如果用户点击返回并转到第一个屏幕,我想显示更新后的列表。

我想使用 NSUserDefaults 来保存我的数组并在屏幕之间显示更新的数据。但我收到下一个错误:

Type '[Dictionary<String, Any>]' does not conform to protocol 'AnyObject'

【问题讨论】:

应该是 AnyObject 而不是 Any。 【参考方案1】:

编辑/更新:在 Swift 3 中,您的字典类型可以。

字典

Swift 还在 Dictionary 类型和 NSDictionary 之间架起了一座桥梁 班级。当您从带有参数化的 NSDictionary 对象桥接时 类型到 Swift 字典,结果字典的类型是 [Key: 价值]。 如果一个 NSDictionary 对象没有指定参数化类型,它是 桥接到 [AnyHashable: Any] 类型的 Swift 字典

因此,在 Swift 3 中将您的字典数组声明为 [[String: Any]] 就可以了:


Xcode 8 • Swift 3

var cart: [[String: Any]] = []
cart.append(["name": "A", "price": 19.99, "qty": 1])
cart.append(["name": "B", "price": 4.99, "qty": 2])

UserDefaults.standard.set(cart, forKey: "myCart")

if let loadedCart = UserDefaults.standard.array(forKey: "myCart") as? [[String: Any]] 
    print(loadedCart)  // [[price: 19.99, qty: 1, name: A], [price: 4.99, qty: 2, name: B]]"
    for item in loadedCart 
        print(item["name"]  as! String)    // A, B
        print(item["price"] as! Double)    // 19.99, 4.99
        print(item["qty"]   as! Int)       // 1, 2
    



您只需要更改声明字典数组的方式。您应该使用[String: AnyObject] 而不是[String: Any]。你应该这样做:

斯威夫特 2.3

var cart: [[String: AnyObject]] = []
cart.append(["name": "A", "price": 19.99, "qty": 1])
cart.append(["name": "B", "price": 4.99, "qty": 2])

NSUserDefaults().setObject(cart, forKey: "myCart")

if let loadedCart = NSUserDefaults().arrayForKey("myCart") as? [[String: AnyObject]] 
    print(loadedCart)  // [[price: 19.99, qty: 1, name: A], [price: 4.99, qty: 2, name: B]]"

    for item in loadedCart 
        print(item["name"] as! String)  // A, B
        print(item["price"] as! Double) // 19.99, 4.99
        print(item["qty"] as! Int)      // 1, 2
    

【讨论】:

美丽有用的答案。【参考方案2】:

这是因为您试图将数组存储为“AnyObject”。

你需要做的是:

var counter = 0
for c in cart

      userDefaults.setObject(c, forKey: "cart\(counter)")
      counter++

然后您可以像这样访问您的字典:

let yourCartZero = userDefaults.objectForKey("cart0")

如果要同时存储整个数组:

那么你可以使用这个:

var saving: Dictionary<String, [Dictionary<String, Any>]>

var cart: [Dictionary<String, Any>] = []

var savingCart: Dictionary<String, [Dictionary<String, Any>]> = ["savedCard" : cart]

userDefaults.setObject(savingCart, forKey: "Carts")

【讨论】:

【参考方案3】:

您正在使用不符合 AnyObject 的 Any。使用 AnyObject 来声明你的字典,

var cart: [Dictionary<String, AnyObject>] = [["name": "A", "price": "1", "qty": "3"],["name": "B", "price": "2", "qty": "1"]]

【讨论】:

以上是关于Swift - 将字典数组保存到 NSUserDefaults的主要内容,如果未能解决你的问题,请参考以下文章

使用谓词的字典过滤器数组 - swift3

将对象数组映射到 Swift 中的字典

将字典映射到 Swift 中的结构数组

Swift 4 通过外键将数组映射到字典

Swift 3:数组到字典?

Swift & Firestore - 使用 .arrayUnion() 将字典附加到嵌套数组