在 swift 中循环遍历 plist

Loop through plist in swift

嘿伙计们,我目前正在尝试遍历这样设置的 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?' 符合 'Sequence';您是要展开可选的吗?

我从 loop through nested NSDictionary in plist using swift 中获取了代码,它似乎与我的结构化 plist 相同,所以我不确定为什么它不起作用。遍历我的 plist 的最佳方式是什么?

使用 if let 安全解包 letterPoints:

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

首先,根本不要使用 NSDictionary/NSArray API 来阅读 Swift 中的 属性 列表。

NSDictionary(contentsOfFile returns 一个可选的,你必须打开它才能在循环中使用它,这就是错误告诉你的内容。

并且 属性 列表中没有字典,只有根对象。所有其他集合类型都是数组(截图中清楚说明)

强烈建议 API 阅读 Swift 中的 属性 列表是 PropertyListSerialization 甚至 Swift 中的 PropertyListDecoder 4+

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

由于 属性 列表在应用程序包中是(不可变的)强制解包选项很好。如果代码崩溃,它会揭示一个可以立即修复的设计错误。