如何将 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 内容不为空时。
我正在尝试将 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 内容不为空时。