大家好,我目前正在尝试遍历这样设置的plist:
我正在使用的代码:
letterPoints = NSDictionary(contentsOfFile: Bundle.main.path(forResource: "LetterPoints", ofType: "plist")!)
for (myKey, myValue) in letterPoints {
for (key, value) in myValue as NSDictionary {
let x = value["Item 0"] as NSNumber
let y = value["Item 1"] as NSNumber
// lastPoint: CGPoint = CGPoint(x: x.integerValue, y: y.integerValue)
println("x: \(x); y: \(y)")
}
}
但是我在循环的第一行中遇到了错误:for-in循环需要“ NSDictionary?”符合“顺序”;您是说要拆开可选包装吗?
我从loop through nested NSDictionary in plist using swift中获取了代码,它似乎与我的结构化plist相同,因此不确定它为什么不起作用。遍历我的plist的最佳方法是什么?
答案 0 :(得分:2)
首先完全不使用NSDictionary/NSArray
API来读取Swift中的属性列表。
NSDictionary(contentsOfFile
返回一个可选内容,您必须解开它才能在循环中使用它,这就是错误告诉您的内容。
除了属性列表中的根对象外,没有字典。所有其他集合类型都是数组(在屏幕截图中已明确说明)
强烈推荐在Swift中读取属性列表的API是PropertyListSerialization
甚至在Swift 4+中是PropertyListDecoder
let url = Bundle.main.url(forResource: "LetterPoints", withExtension: "plist")!
let data = try! Data(contentsOf: url)
let letterPoints = try! PropertyListSerialization.propertyList(from: data, format: nil) as! [String:[[Int]]]
for (_, outerArray) in letterPoints {
for innerArray in outerArray {
let x = innerArray[0]
let y = innerArray[1]
print("x: \(x); y: \(y)")
}
}
由于应用程序捆绑包中的属性列表是(不可变的),因此可以强制展开可选对象。如果代码崩溃,则表明存在设计错误,可以立即修复。
答案 1 :(得分:0)
用letterPoints
安全解开if let
:
if let letterPoints = NSDictionary(contentsOfFile: Bundle.main.path(forResource: "LetterPoints", ofType: "plist")!) {
// Use letterPoints in here
for (myKey, myValue) in letterPoints {
// Iterate in here
}
}
请注意,看起来迭代器使用了错误的类型。您的plist看起来像是具有String
键和[NSNumber]
值的NSDictionary。您可以像这样遍历它:
if let letterPoints = NSDictionary(contentsOfFile: Bundle.main.path(forResource: "LetterPoints", ofType: "plist")!) as? [String: [NSNumber]] {
for (_, myValue) in letterPoints {
let x = myValue[0]
let y = myValue[1]
// lastPoint: CGPoint = CGPoint(x: x.integerValue, y: y.integerValue)
print("x: \(x); y: \(y)")
}
}