如何将 NSDictionary 存储在 String:String 中?

How can I store an NSDictionary in a String:String?

我正在尝试将 plist(键是唯一的单词,值是它们的英语定义)加载到字典中。 我可以这样一次性完成:

let definitionsFile = URL(fileURLWithPath: Bundle.main.path(forResource: "word_definitions", ofType:"plist")!)
let contents = NSDictionary(contentsOf: definitionsFile)
guard let value = contents!.object(forKey: lastGuess) as? String else {
      print("value from key fail")
      return
} 

...但每次我使用它时都必须加载文件。所以我尝试将代码移动到程序加载器并将数据存储在定义字典中(大写的消息是问题区域):

let definitionsFile = URL(fileURLWithPath: Bundle.main.path(forResource: "word_definitions", ofType:"plist")!)
if let contents = NSDictionary(contentsOf: definitionsFile) as? [String : String] {
    print("loaded definitions dictionary")
    if case state.definitions = contents {
        print("added definitions to state")
    } else {
        print("FAILED TO ADD DEFINITIONS TO STATE")
    }
} else {
    print("failed to load definitions dictionary")
}

它在我将它分配给 state.definitions(这是一个 String:String 字典)时失败了。有什么我想念的吗?我是否需要将 state.definitions 更改为 String:Any 并重写每次访问?

更新:根据 Tom Harrington 的评论,我尝试显式创建 state.definitions 作为 NSDictionary(删除 as [String:String] 位),但它仍然没有存储字典。

我把你的代码放在一个 Playground 中,它生成一个 plist 文件,然后使用 NSDictionary 来解析它。这是完整的游乐场

import Foundation

let stringPairs = [
    "One" : "For the Money",
    "Two" : "For the Show",
    "Three" : "To Get Ready",
    "Four" : "To Go",
]

let tempDirURL = FileManager.default.url(for: .itemReplacementDirectory,
                                      in: .userDomainMask,
                                      appropriateFor: Bundle.main.bundleURL,
                                      create: true)
let demoFileURL = tempDirURL.appendingPathComponent("demo_plist.plist")
do {
    if let plistData = try? PropertyListSerialization.data(
        fromPropertyList: stringPairs,
        format: .xml,
        options: 0) {
        try plistData.write(to: demoFileURL)
    }
} catch {
    print("Serializing the data failed")
}

struct State {
    var definitions: [String: String]
}

var state = State(definitions: [:])

if let fileContent = NSDictionary(contentsOf: demoFileURL),
   let contents = fileContent as? [String : String] {
    print("loaded definitions dictionary")
    state.definitions = contents
} else {
    print("failed to load definitions dictionary")
}

debugPrint(state.definitions)

请注意,我刚刚为 state 变量及其类型编写了一些内容。

它似乎工作正常并打印:

loaded definitions dictionary
["Four": "To Go", "Two": "For the Show", "One": "For the Money", "Three": "To Get Ready"]

我更改的一件事是您的 if case ... 声明。我完全确定这个结构在这种情况下意味着什么。 Swift 语言指南说 if case 后面应该跟一个模式和一个初始值设定项。在我的代码中,“state.definitions”不是模式,因此 if case 总是 returns 错误。但在我看来,这应该是某种编译器错误。

无论如何,通过将 contents 的绑定拉到它自己的外部 if 子句中,我可以确定当我进入 if 内容不为空时。