JSON 个对象 Swift 5

JSON objects in Swift 5

我正在尝试访问 json api 中的数据,如下所示

"Products": [
            {
                "ProductName": "GR",
                "ShortDescription": "General service epoxy mortar system that utilizes recycled glass and rapidly renewable soy based components.",
                "PDSOverride": [
                    {
                        "FileName": "EcoLab Netherlands",
                        "FileUrl": "http://test.stonhard.com/media/2264/eco-lab-netherlands-usa-version.pdf"
                    },
                    {
                        "FileName": "General Dynamics.pdf",
                        "FileUrl": "http://test.stonhard.com/media/2060/general-dynamics.pdf"
                    }
                ]
            }
        ]

我正在用下面这样的结构对其进行建模

struct Solutions: Codable, Identifiable {
    let id = UUID()
    let SectionTitle: String
    let SectionImage: String
    let ProductLines: [ProductLine]
}

struct ProductLine: Codable {
    let System: String
    let Products: [Product]
}

struct Product: Codable {
    let ProductName: String
    let ShortDescription: String
    let PDSOverride: [PDSOverride]
}

struct PDSOverride: Codable {
    let FileName: String
    let FileUrl: String
}

struct SdsPdf: Codable {
    let FileName: String
    let FileUrl: String
}

struct GuideSpecPdf: Codable {
    let FileName: String
    let FileUrl: String
}   

当我尝试访问数据时,我收到一条错误消息,提示无法读取数据,因为它的格式不正确。我知道这是我的模型的问题,因为当我注释掉 PDSOverride、SdsPdf 和 GuideSpecPdf 时它起作用了,但显然我无权访问该数据。如何为我的结构建模以便提取数据?

假设你的 JSON 只是缺少右大括号,你可以这样解析它:

struct Entry: Codable {
    let products: [Product]

    enum CodingKeys: String, CodingKey {
        case products = "Products"
    }
}

struct Product: Codable {
    let productName, shortDescription: String
    let pdsOverride: [PDSOverride]

    enum CodingKeys: String, CodingKey {
        case productName = "ProductName"
        case shortDescription = "ShortDescription"
        case pdsOverride = "PDSOverride"
    }
}

struct PDSOverride: Codable {
    let fileName: String
    let fileURL: String

    enum CodingKeys: String, CodingKey {
        case fileName = "FileName"
        case fileURL = "FileUrl"
    }
}

do {
    let entries = try JSONDecoder().decode([Entry].self, from: data)
} catch {
    print(error)
}

问题不在您的模型中,您的 JSON 格式错误,正如编译器所说,您的 JSON 需要看起来像这样:

[
    { 
        "Products": [
            {
                "ProductName": "GR",
                "ShortDescription": "General service epoxy mortar system that utilizes recycled glass and rapidly renewable soy based components.",
                "PDSOverride": [
                    {
                        "FileName": "EcoLab Netherlands",
                        "FileUrl": "http://test.stonhard.com/media/2264/eco-lab-netherlands-usa-version.pdf"
                    },
                    {
                        "FileName": "General Dynamics.pdf",
                        "FileUrl": "http://test.stonhard.com/media/2060/general-dynamics.pdf"
                    }
                ]
            }
        ]
    }
]

另外,这个模型也可以这样搞,推荐你用Quicktype(https://app.quicktype.io) 在线版不错,他们有桌面版:

// MARK: - PurpleProduct
struct PurpleProduct: Codable {
    let products: [ProductProduct]

    enum CodingKeys: String, CodingKey {
        case products = "Products"
    }
}

// MARK: - ProductProduct
struct ProductProduct: Codable {
    let productName, shortDescription: String
    let pdsOverride: [PDSOverride]

    enum CodingKeys: String, CodingKey {
        case productName = "ProductName"
        case shortDescription = "ShortDescription"
        case pdsOverride = "PDSOverride"
    }
}

// MARK: - PDSOverride
struct PDSOverride: Codable {
    let fileName: String
    let fileURL: String

    enum CodingKeys: String, CodingKey {
        case fileName = "FileName"
        case fileURL = "FileUrl"
    }
}

typealias Products = [PurpleProduct]

要解码你可以使用JSON解码器,我也建议你在这个页面检查你的json:https://jsonformatter.curiousconcept.com