gpt4 book ai didi

ios - 尝试在 iOS 中解析动态 JSON

转载 作者:行者123 更新时间:2023-11-28 07:30:49 25 4
gpt4 key购买 nike

我生成了以下 JSON 示例 block 。任何以字母结尾的值都是动态的。

{
"groupName": {
"groupA": {
"fields": {
"fieldA": "valueA",
"fieldB": "valueB"
},
"letters": {
"letterA: "A"
}
},
"groupB": {
"fields": {
"fieldC": "valueC",
"fieldD": "valueD"
},
"letters": {
"letterB: "B"
}
}
}
}

我的目标是使用 Decodable,这样我就可以将这些数据读入我定义的 struct 中。

下面是我用来尝试解决此问题的 playground 文件中包含的当前工作:

import Foundation

let jsonString = "{\"groupName\":{\"groupA\":{\"fields\":{\"fieldA\":\"valueA\",\"fieldB\":\"valueB\"},\"letters\":{\"letterA:\"A\"}},\"groupB\":{\"fields\":{\"fieldC\":\"valueC\",\"fieldD\":\"valueD\"},\"letters\":{\"letterB:\"B\"}}}}"

struct CustomCodingKeys: CodingKey {
var intValue: Int?
var stringValue: String

init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
init?(stringValue: String) { self.stringValue = stringValue }

static let field = CustomCodingKeys.make(key: "field")

static func make(key: String) -> CustomCodingKeys {
return CustomCodingKeys(stringValue: key)!
}
}

// Values
struct Field {
let field: String
let value: String
}

struct Letter: Decodable {
let title: String
let letter: String
}

// Value holders
struct FieldData: Decodable {
var fields: [Field]

init(from decoder: Decoder) throws {
self.fields = [Field]()
let container = try decoder.container(keyedBy: CustomCodingKeys.self)
for key in container.allKeys {
print("processing field: \(key.stringValue)")
let dynamicKey = CustomCodingKeys.make(key: key.stringValue)
let value = try container.decode(String.self, forKey: dynamicKey)
let field = Field(field: key.stringValue,
value: value)
fields.append(field)
}
}
}

struct LetterData: Decodable {
var letters: [Letter]

init(from decoder: Decoder) throws {
self.letters = [Letter]()
let container = try decoder.container(keyedBy: CustomCodingKeys.self)
for key in container.allKeys {
print("processing letter: \(key.stringValue)")
let dynamicKey = CustomCodingKeys.make(key: key.stringValue)
let value = try container.decode(String.self, forKey: dynamicKey)
let letter = Letter(title: key.stringValue,
letter: value)
letters.append(letter)
}
}
}

// Containers
struct Group: Decodable {
var name: String!
var groups: [GroupData]

init(from decoder: Decoder) throws {
self.groups = [GroupData]()
let container = try decoder.container(keyedBy: CustomCodingKeys.self)
for key in container.allKeys {
print("processing section: \(key.stringValue)")
let group = try container.decode(GroupData.self,
forKey: key)
groups.append(group)
}
}
}

struct GroupData: Decodable {
var fieldData: FieldData
var letterData: LetterData

enum CodingKeys: String, CodingKey {
case fieldData = "fields"
case letterData = "letters"
}
}

struct GroupList: Decodable {
struct GroupName: Decodable {
var name: String!
var groups: [Group]

init(from decoder: Decoder) throws {
self.groups = [Group]()

let container = try decoder.container(keyedBy: CustomCodingKeys.self)
for key in container.allKeys {
let name = key.stringValue
self.name = name
print("processing group: \(String(describing: self.name))")
var group = try container.decode(Group.self,
forKey: key)
group.name = name
groups.append(group)
}
}
}

let groupName: GroupName
}

let decoder = JSONDecoder()
if let data = jsonString.data(using: .utf8),
let groupList = try? decoder.decode(GroupList.self,
from: data) {
print("group list created")
}

在我的 GroupData 结构中,我可以删除变量然后实现 init(from decoder: Decoder) throws,当配置了正确的查找(FieldData & LetterData inits),可以识别正确的对。但是,它不会填充正确的值结构。

最佳答案

你在解码 Group 时犯了一个小错误。您倾向于解码 Group 中组的所有键,并且您还进一步传递解码 GroupData 本身具有“字段”和“字母”。在 Group 中使用单值容器,应该没问题。

这是您的 Group 的外观,

struct Group: Decodable {
var name: String!
var groups: GroupData

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
groups = try container.decode(GroupData.self)
}
}

注意,你的json本身是错误的,我已经格式化了,应该是这样的,

let jsonString = "{\"groupName\":{\"groupA\":{\"fields\":{\"fieldA\":\"valueA\",\"fieldB\":\"valueB\"},\"letters\":{\"letterA\":\"A\"}},\"groupB\":{\"fields\":{\"fieldC\":\"valueC\",\"fieldD\":\"valueD\"},\"letters\":{\"letterB\":\"B\"}}}}"

关于ios - 尝试在 iOS 中解析动态 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54775272/

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