Сохраните вложенный словарь в UserDefaults и управляйте проверкой дублирования [Swift 4.2] - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть вложенный словарь, необходимый для сохранения в UserDefaults и отправки в расширение.Структура словаря, как показано ниже:

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"]],
        ]
    ]

Который успешно сохранен с помощью:

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

Но теперь я хочу вернуть его и проверить, существует ли Title2, если да, то удалите его идобавьте еще раз с новыми пунктами

Я имел обыкновение делать следующее, но не могу вернуть заголовок:

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

успешно, чтобы получить данные в разделе "Разделы" с помощью следующего кода

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

, но не удалось получить заголовок с помощью:

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

Я тоже пытался (ключ, значение), но выдал ошибку типа данных

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

Могу ли язнаете, есть ли способ вернуть «Заголовок» для проверки и обновления?Я использую неправильный способ хранения такого рода вложенных данных?

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

в вашем коде

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

здесь должно быть

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

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

, как будто сейчас в вашем словаре есть три элемента в разделе, так что можно безопасно получить значение в 0, надеюсьвы поняли, что базовый словарь - это массив словаря в ключе секций, также вместо словаря вы можете использовать struct или класс для сохранения ваших данных и, получая их, извлекать их как этот тип структуры.

0 голосов
/ 09 февраля 2019

Прежде всего, никогда не используйте метод KVC setValue(:forKey с UserDefaults.

Есть общий set(:forKey.И есть dictionary(forKey:, чтобы получить [String:Any] словарь обратно

Значение для ключа Sections является массивом (на основе индекса).Предположим, у вас есть эти новые данные

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

Это способ загрузки словаря - вы всегда должны безопасно проверять, существует ли словарь - обновите его и сохраните обратно.Если элемент для "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")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...