从 PropertyList 解码数据

Decode data from PropertyList

我想从属性列表中获取数据,属性列表的结构是这样的

这是源文件 xml

<array>
    <dict>
        <key>imageIcon</key>
        <string>air-compressor.png</string>
        <key>toolsName</key>
        <string>Air Compressor</string>
        <key>items</key>
        <array>
            <dict>
                <key>item</key>
                <string>Air Compressor 1</string>
                <key>borrower</key>
                <string></string>
            </dict>
            <dict>
                <key>item</key>
                <string>Air Compressor 2</string>
                <key>borrower</key>
                <string></string>
            </dict>
        </array>
    </dict>
</array>
</plist>

我这样构建我的对象模型

struct ToolsItem: Codable {
    var tools: [Tools]
}

struct Tools: Codable {
    let imageIcon: String
    let toolsName: String
    var items: [Items]
}

struct Items: Codable {
    let itemName: String
    let borrower: String
}

并像这样设置我的数据管理器

class DataManager {
    
    static let shared = DataManager()
    
    func fetch() {
        guard let path = Bundle.main.path(forResource: "ToolsData", ofType: "plist") else { return }
        let url = URL(fileURLWithPath: path)
        
        do {
            let data = try Data(contentsOf: url)
            
            let items = try PropertyListDecoder().decode(ToolsItem.self, from: data)
            print(items.tools)
        } catch {
            print(error)
        }
        
    }
}

但是 return

"Expected to decode Dictionary<String, Any> but found an array instead." and no data being show.

如果像这样更改我的数据管理器

let items = try PropertyListDecoder().decode([ToolsItem].self, from: data)

错误return

keyNotFound(CodingKeys(stringValue: "tools", intValue: nil), Swift.DecodingError.Context(codingPath: [_PlistKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "tools", intValue: nil) ("tools").", underlyingError: nil))

如何从plist中正确获取数据?

您的结构应该如下所示。

import Foundation

struct ToolsItem: Codable {
    let imageIcon: String
    let toolsName: String
    let items: [Items]
}

struct Items: Codable {
    let item: String
    let borrower: String
}

// 对于视图控制器 //

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if let path = Bundle.main.path(forResource: "ToolsData", ofType: "plist") {
        let fileURL = URL(fileURLWithPath: path)
        do {
            let data = try Data(contentsOf: fileURL)
            let items = try PropertyListDecoder().decode([ToolsItem].self, from: data)
            print("Items: \(items)")
        } catch let error as NSError {
            print("\(error)")
        }
    }
}