快速遍历plist

时间:2020-04-13 00:25:34

标签: ios swift nsdictionary swift-optionals

大家好,我目前正在尝试遍历这样设置的plist:

enter image description here

我正在使用的代码:

    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的最佳方法是什么?

2 个答案:

答案 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)")
    }
}