简体   繁体   English

将嵌套词典保存在UserDefaults中并管理重复检查[Swift 4.2]

[英]Save Nested Dictionary in UserDefaults and manage the duplication check [Swift 4.2]

I have a nested Dictionary required to save in UserDefaults and share to extension. 我有一个嵌套的Dictionary需要保存在UserDefaults中并共享给扩展名。 The dictionary structure like below: 字典结构如下:

let dict = [
        "Sections" : [
            ["Title" : "Title1", "Items": ["item1-1", "item1-2", "item1-3"]],
            ["Title" : "Title2", "Items": ["item2-1", "item2-2", "item2-3", "item2-4"]],
            ["Title" : "Title3", "Items": ["item3-1"]],
        ]
    ]

Which saved successfully with: 使用以下命令成功保存:

UserDefaults(suiteName: "group.identifier.test")!.setValue(dict, forKey: "savedDict")

But now I wish to get it back and check is Title2 already exists, if yes then delete it and add again with new Items 但是现在我希望找回它并检查Title2是否已经存在,如果是,则将其删除并再次添加新项

I used to do following but can't get the Title back: 我曾经做过以下事情,但无法获得标题:

let savedDict:[String:AnyObject] = UserDefaults(suiteName: "group.identifier.test")!.object(forKey: "savedDict") as! Dictionary

success to get the data under "Sections" by following code 通过以下代码成功获取“部分”下的数据

let savedSection = savedDict["Sections"]
print("Saved Section: \(savedSection)")

but not able to get the Title with: 但无法通过以下方式获得标题:

print("Saved Title: \(savedSection!["Title"])") *// return nil*

I tried for (key, value) too, but fired a data type error 我也尝试了(键,值),但触发了数据类型错误

for (key, value) in savedSection{  *// Type 'AnyObject?' does not conform to protocol 'Sequence'*
    print("Key: \(key) Value: \(value)")
}

May I know is there any way to get the "Title" back for checking and update? 我可以知道有什么方法可以找回“标题”进行检查和更新吗? Am I using the wrong way to store this kind of nested data? 我使用错误的方式来存储这种嵌套数据吗?

Many Thanks! 非常感谢!

in your code 在你的代码中

 print("Saved Title: \(savedSection!["Title"])") *// return nil*

here it should be 在这里应该

  if let savedSection = savedDict["Sections"] as?  [[String : Any]] { //EDIT***

      print("Saved Title: \(savedSection[0]["Title"])") *// inplace of 0 any index you want, 
  }

as if now in your dictionary there are three elements in section so it safe to get value at 0, hope you understood that the underlying dictionary is array of dictionary in sections key, also instead of using dictionary you can use struct or class to save your data and while getting it retrieve it as that struct type. 就像现在字典中的节中有三个元素一样,因此可以安全地将值设为0,希望您理解基础字典是节键中的字典数组,也可以使用struct或class来代替使用Dictionary来保存您的字典数据,并在获取数据时将其检索为该结构类型。

First of all, never use KVC method setValue(:forKey with UserDefaults . 首先,永远不要将KVC方法setValue(:forKeyUserDefaults一起UserDefaults

There is generic set(:forKey . And there is dictionary(forKey: to get a [String:Any] dictionary back 有一个通用的set(:forKey 。还有一个dictionary(forKey:返回一个[String:Any]字典。

The value for key Sections is an array (index-based). 关键Sections的值是一个数组(基于索引)。 Lets assume you have this new data 假设您有这个新数据

let newTitle2 : [String:Any] = ["Title" : "Title2", "Items": ["item4-1", "item4-2", "item4-3"]]

This is a way to load the dictionary – you should always safely check if the dictionary exists – update it and save it back. 这是加载词典的一种方法–您应始终安全地检查词典是否存在–更新并保存。 If the item for "Title2" exists it will be overwritten otherwise the new item is appended to the array. 如果"Title2"的项目存在,它将被覆盖,否则新项目将附加到数组中。

let groupDefaults = UserDefaults(suiteName: "group.identifier.test")!
if var savedDict = groupDefaults.dictionary(forKey: "savedDict"), 
   var sections = savedDict["Sections"] as? [[String:Any]] {
      if let title2Index = sections.firstIndex(where: {($0["Title"] as! String) == "Title2"}) {
         sections[title2Index] = newTitle2
      } else {
         sections.append(newTitle2)
      }
      savedDict["Sections"] = sections
      groupDefaults.set(savedDict, forKey: "savedDict")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM