复杂JSON到Swift
因此,我对JSON和将其转换为Swift比较陌生。我只处理了简单数据类型的基本JSON。没什么特别的。我还只讨论了如何使用我创建的JSON 现在我正在尝试使用从JSON和API收集的JSON。此JSON在其他对象中嵌套了对象 以下是JSON的格式:复杂JSON到Swift,json,swift,Json,Swift,因此,我对JSON和将其转换为Swift比较陌生。我只处理了简单数据类型的基本JSON。没什么特别的。我还只讨论了如何使用我创建的JSON 现在我正在尝试使用从JSON和API收集的JSON。此JSON在其他对象中嵌套了对象 以下是JSON的格式: { "records": [ { "id": "Info", "fields": { "Card
{
"records": [
{
"id": "Info",
"fields": {
"Card Name": "Info",
"Qty": 0,
"Card Type": "Info",
"Color": "Info",
"Card #": "Info",
"Rarity": "Info",
"Image": [
{
"id": "Info",
"url": "url",
"filename": "info",
"size": 0,
"type": "info",
"thumbnails": {
"small": {
"url": "url",
"width": 0,
"height": 0
},
"large": {
"url": "url",
"width": 0,
"height": 0
},
"full": {
"url": "url",
"width": 0,
"height": 0
}
}
}
],
"Level": 0,
"Full Set": 0
},
"createdTime": "info"
}
],
"offset": "info"
}
我不确定我是否需要对“记录”部分做些什么。现在“记录”数组中有更多的记录
我不需要每个记录中的所有信息
我试过这样做:
struct Card {
let offSet: String
let cardName: String
}
extension Card: Decodable {
enum CodingKeys: String, CodingKey {
case offSet
case cardName
enum FieldKeys: String, CodingKey {
case cardName = "Card Name"
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
offSet = try container.decode(String.self, forKey: .offSet)
let fieldContainer = try container.nestedContainer(keyedBy: CodingKeys.FieldKeys.self, forKey: .cardName)
cardName = try fieldContainer.decode(String.self, forKey: .cardName)
}
}
每次我试着将信息解码到我的Swift结构中,结果都是零。我不知道我做错了什么,也不知道该怎么办。我没有处理过有“记录”的JSON:设置如下。不知道这是否重要
还有一个关于图像的附带问题。我会使用url属性来显示图像吗?图像文件将是PNG。以前从未处理过图像和JSON。正如Larme评论的那样,“您的代码无法猜测”——这意味着您需要在代码中表示JSON提供的相同结构 在为您做这项工作的危险中,我已经编写了一套非常详细的
Codable
struct
,从您提供的JSON中提取所有数据
struct Card: Codable {
var records:[Record]
var offset:String
}
struct Record: Codable {
var id:String
var fields:Fields
var createdTime:String
}
struct Fields: Codable {
var name:String
var quantity:Int
var type:String
var color:String
var number:String
var rarity:String
var level:Int
var fullSet:Int
var image:[Image]
enum CodingKeys: String, CodingKey {
case name = "Card Name"
case quantity = "Qty"
case type = "Card Type"
case color = "Color"
case number = "Card #"
case rarity = "Rarity"
case level = "Level"
case fullSet = "Full Set"
case image = "Image"
}
}
struct Image: Codable {
var id:String
var url:String
var filename:String
var size:Int
var type:String
var thumbnails:Thumbnails
}
struct Thumbnails: Codable {
var small:Thumbnail
var large:Thumbnail
var full:Thumbnail
}
struct Thumbnail: Codable {
var url:String
var width:Int
var height:Int
}
我在一个操场上测试了上述内容,将您提供的JSON粘贴为多行字符串,并使用以下命令转储生成的对象
do {
if let data = json.data(using: .utf8) {
let card = try JSONDecoder().decode(Card.self, from: data)
dump(card)
}
} catch {
fatalError("Failed to decode \(error)")
}
其产出为:
▿ __lldb_expr_21.Card
▿ records: 1 element
▿ __lldb_expr_21.Record
- id: "Info"
▿ fields: __lldb_expr_21.Fields
- name: "Info"
- quantity: 0
- type: "Info"
- color: "Info"
- number: "Info"
- rarity: "Info"
- level: 0
- fullSet: 0
▿ image: 1 element
▿ __lldb_expr_21.Image
- id: "Info"
- url: "url"
- filename: "info"
- size: 0
- type: "info"
▿ thumbnails: __lldb_expr_21.Thumbnails
▿ small: __lldb_expr_21.Thumbnail
- url: "url"
- width: 0
- height: 0
▿ large: __lldb_expr_21.Thumbnail
- url: "url"
- width: 0
- height: 0
▿ full: __lldb_expr_21.Thumbnail
- url: "url"
- width: 0
- height: 0
- createdTime: "info"
- offset: "info"
一旦你有了所有的数据,你就可以开始简化事情了,也许是得到第一个记录名的卡片的扩展
extension Card {
var cardName:String {
guard let firstRecord = self.records.first else {
return "Unknown Name"
}
return firstRecord.fields.name
}
}
print(card.cardName) // "Info\n"
发生这种情况时,您的代码是什么?但是
记录
是一个数组(可能是多个值),发生这种情况时,您需要哪个卡名
?你需要通过这个结构。你的代码猜不出字段CardName
在记录之后,它可能在任何地方,也可能在字段之后。尝试在线工具将更快地为你生成它,通过练习,你将了解如何自己构造它,这基本上是遵循与响应相同的结构。使用中介结构进行解析会更容易。如果需要,您可以将它们设置为私有,并在顶层struct
上添加一个lazy var
,从中检索所需的值。对于延迟,我们深表歉意。这是我的业余爱好,忙碌的生活的一个附带项目。这是一个巨大的帮助。我能够以此作为指导方针。我还找到了一个教程。在我完全掌握它之前,我通常必须先看看事情是如何运作的。现在我可以进一步完善这个,事实证明,我不需要这些数据。所以我可以修改它,现在我有了一个更好的主意。我将生成不同的JSON结构并进行练习。伟大的起点!!!