gpt4 book ai didi

Swift Codable : parsing JSON with dictionary? 多个不同的条目?

转载 作者:搜寻专家 更新时间:2023-11-01 06:27:00 25 4
gpt4 key购买 nike

我有一个非常大的 Json 文件(几 MB)要解析,但没有合适的文档。生活艰难。据我所知,文件中的对象很容易识别。但是有些事情我不明白,简单的 Codable 协议(protocol)失败了。在数组 layers 中,我可以找到三个 Layer 对象,每个对象都有属性 elements。在 elements 我可以找到多个 elementData - 在第一层有 "ImageID":32dd...component,在第二和第三层 "name":..."contours": [...]。可能会有更多的可能性。我的每次尝试都以错误结束。

抱歉,这段代码会很长,但我不想删减可能很重要的部分:

    "layers":[
{
"name":"img",
"elements":[
{
"elementData":{
"imageId":"32dd800000002"
},
"transform":{
"xScale":100,
"yScale":100
},
"active":true
},
{
"component":{
"glyphName":"e",
"layerName":"img"
}
},
{
"elementData":{
"composite":{
"builder":{
"builderGroup":{
}
}
}
},
"transform":{
"xOffset":120
},
"nonSpacing":true
}
],
"color":"maroon",
"active":true
},
{
"name":"Black",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Black"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"80 577",
"107 549 142 550 167 575 s"
]
}
]
}
}
],
"color":"#00802a"
},
{
"name":"Thin",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Thin"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"102 597 s",
"118 580 132 580 148 597 s",
"250 710",
"235 726",
"110 613",
"140 613",
"14 726",
"-1 710"
]
}
]
}
}
],
"color":"#6a8000"
}
],

如何处理?

最佳答案

https://app.quicktype.io , 正确的 json

{ "layers":[
{
"name":"img",
"elements":[
{
"elementData":{
"imageId":"32dd800000002"
},
"transform":{
"xScale":100,
"yScale":100
},
"active":true
},
{
"component":{
"glyphName":"e",
"layerName":"img"
}
},
{
"elementData":{
"composite":{
"builder":{
"builderGroup":{
}
}
}
},
"transform":{
"xOffset":120
},
"nonSpacing":true
}
],
"color":"maroon",
"active":true
},
{
"name":"Black",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Black"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"80 577",
"107 549 142 550 167 575 s"
]
}
]
}
}
],
"color":"#00802a"
},
{
"name":"Thin",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Thin"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"102 597 s",
"118 580 132 580 148 597 s",
"250 710",
"235 726",
"110 613",
"140 613",
"14 726",
"-1 710"
]
}
]
}
}
],
"color":"#6a8000"
}
]}

解析

struct Welcome: Codable {
let layers: [Layer]
}

struct Layer: Codable {
let name: String
let elements: [Element]
let color: String
let active: Bool?
}

struct Element: Codable {
let elementData: ElementData?
let transform: Transform?
let active: Bool?
let component: Component?
let nonSpacing: Bool?
}

struct Component: Codable {
let glyphName, layerName: String
}

struct ElementData: Codable {
let imageID: String?
let composite: Composite?
let name: String?
let contours: [Contour]?

enum CodingKeys: String, CodingKey {
case imageID = "imageId"
case composite, name, contours
}
}

struct Composite: Codable {
let builder: Builder
}

struct Builder: Codable {
let builderGroup: BuilderGroup
}

struct BuilderGroup: Codable {
}

struct Contour: Codable {
let nodes: [String]
}

struct Transform: Codable {
let xScale, yScale, xOffset: Int?
}

do {
let res = try JSONDecoder().decode(Welcome.self,from:data)
}
catch {
print(error)
}

编辑:

struct Welcome: Codable {
let layers: [Layer]
}

struct Layer: Codable {
let name: String
let elements: [Element]
let color: String
let active: Bool?
}

struct Element: Codable {
let elementData: ElementDataUnion?
let transform: Transform?
let active: Bool?
let component: Component?
let nonSpacing: Bool?
}

struct Component: Codable {
let glyphName, layerName: String
}

enum ElementDataUnion: Codable {
case elementDataClass(ElementDataClass)
case string(String)

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ElementDataClass.self) {
self = .elementDataClass(x)
return
}
throw DecodingError.typeMismatch(ElementDataUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ElementDataUnion"))
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementDataClass(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}

struct ElementDataClass: Codable {
let composite: Composite?
let name: String?
let contours: [Contour]?
}

struct Composite: Codable {
let builder: Builder
}

struct Builder: Codable {
let builderGroup: BuilderGroup
}

struct BuilderGroup: Codable {
}

struct Contour: Codable {
let nodes: [String]
}

struct Transform: Codable {
let xScale, yScale, xOffset: Int?
}

如果你需要 elementData 为字典/字符串 ,,,,, elements 为数组/字符串则使用

struct Welcome: Codable {
let layers: [Layer]
}

struct Layer: Codable {
let name: String
let elements: Elements
let color: String
let active: Bool?
}

enum Elements: Codable {
case elementArray([Element])
case string(String)

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([Element].self) {
self = .elementArray(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Elements.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Elements"))
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementArray(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}

struct Element: Codable {
let component: Component?
let elementData: ElementDataUnion?
}

struct Component: Codable {
let glyphName, layerName: String
}

enum ElementDataUnion: Codable {
case elementDataClass(ElementDataClass)
case string(String)

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ElementDataClass.self) {
self = .elementDataClass(x)
return
}
throw DecodingError.typeMismatch(ElementDataUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ElementDataUnion"))
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementDataClass(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}

struct ElementDataClass: Codable {
let name: String
let contours: [Contour]
}

struct Contour: Codable {
let nodes: [String]
}

关于Swift Codable : parsing JSON with dictionary? 多个不同的条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53047238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com