将 JSON 响应解析为结构
Posted
技术标签:
【中文标题】将 JSON 响应解析为结构【英文标题】:Parsing JSON response into a struct 【发布时间】:2019-05-29 19:06:08 【问题描述】:我正在使用 Alamofire 并以 JSON 格式从 API 取回数据。 我想将数据用于结构。 响应如下:
"status" : 1,
"data" : [
"classes" : [
],
"day" : "Wednesday"
,
"classes" : [
"time" : "1:30 PM",
"available_spots" : 2,
"trainer" : "Ahmed Jasim",
"thumbnail" : "\/uploads\/classes\/6\/files\/class_6_15555066955cb72607131886.71740331.jpg",
"id" : 6,
"name" : "Gym Class C"
],
"day" : "Thursday"
,
"classes" : [
],
"day" : "Friday"
,
"classes" : [
],
"day" : "Saturday"
,
"classes" : [
"available_spots" : 2,
"id" : 1,
"trainer" : "Ahmed Jasim",
"name" : "Karate",
"thumbnail" : "\/uploads\/classes\/1\/files\/class_1_15548800215cad9615e62404.41767774.jpg",
"time" : "5:00 PM"
],
"day" : "Sunday"
,
"classes" : [
"thumbnail" : "\/uploads\/classes\/1\/files\/class_1_15548800215cad9615e62404.41767774.jpg",
"available_spots" : 2,
"time" : "11:00 AM",
"name" : "Karate",
"id" : 1,
"trainer" : "Ahmed Jasim"
,
"trainer" : "Jalal Hassan",
"available_spots" : 20,
"thumbnail" : "\/uploads\/classes\/2\/files\/class_2_15548819805cad9dbc7b9a80.11639647.jpg",
"time" : "4:00 PM",
"name" : "Gym Class B",
"id" : 2
],
"day" : "Monday"
,
"classes" : [
"name" : "Gym Class B",
"trainer" : "Jalal Hassan",
"time" : "9:00 AM",
"available_spots" : 20,
"id" : 2,
"thumbnail" : "\/uploads\/classes\/2\/files\/class_2_15548819805cad9dbc7b9a80.11639647.jpg"
],
"day" : "Tuesday"
],
"message" : "Retrieved successfully",
"success" : true
我想获取“day & classes”并在结构中使用它们。 我使用的结构如下。
struct section
day: String!
classes: [String]!
所以我想得到一天和它的类并存储它们。 对结构的调用:
var sections = [Section(day: "Monday", classes: ["A","B","C"]]
我想要实现的是得到所有的日子和它的类 & 如果一天没有类它只是一个空数组。
但我不确定这是否可能。
这是 Alamofire 请求中的代码:
let classesJSON: JSON = JSON(response.result.value!)
if response.data != nil
for index in 0..<classesJSON["data"].count
var sections = Section(day: classesJSON["data"][index]["day"].stringValue, classes: [])
for data in classesJSON["data"].arrayValue
for value in data["classes"].arrayValue
sections.classes.append(value["name"].stringValue)
//sections.classes[index] = value["name"].stringValue
print(sections)
我的问题是我得到了响应中的所有课程,我想要的是获得当天的特定课程。
Section(day: Optional("Sunday"), classes: Optional(["Gym Class C", "Karate", "Karate", "Gym Class B", "Gym Class B"])
Section(day: Optional("Monday"), classes: Optional(["Gym Class C", "Karate", "Karate", "Gym Class B", "Gym Class B"])
^这是我得到的,但我想把它们分开,这样我就可以得到一天和它的课程,而不是全部
【问题讨论】:
如果你想将 JSON 解析成结构(一个是不够的)SwiftyJSON 是不合适的。使用Codable
。相关问题数不胜数。
【参考方案1】:
我建议放弃 SwiftyJSON 并使用带有 Codable
的真实模型对象。
使用以下结构解析数据:
struct APIResponse: Codable
let status: Int
let data: [ClassData]
let message: String
let success: Bool
struct ClassData: Codable
let classes: [Class]
let day: String
struct Class: Codable
let time: String
let availableSpots: Int
let trainer, thumbnail: String
let id: Int
let name: String
enum CodingKeys: String, CodingKey
case time
case availableSpots = "available_spots"
case trainer, thumbnail, id, name
struct Section
let day: String
let classes: [String]
do
let response = try JSONDecoder().decode(APIResponse.self, from: json)
let classesPerDay: [String: [Class]] = response.data.reduce(into: [:])
$0[$1.day, default: []].append(contentsOf: $1.classes)
let sections = classesPerDay.map Section(day: $0, classes: $1.map $0.name )
print(sections)
catch
print(error)
【讨论】:
【参考方案2】:你可以稍微改变你的循环
for index in 0..<classesJSON["data"].count
var classes: [String] = []
for item in classesJSON["data"][index]["classes"].arrayValue
classes.append(item["name"].stringValue)
let sections = Section(day: classesJSON["data"][index]["day"].stringValue, classes: classes)
print(sections)
并确保将结构中的日期和课程的 let 更改为 var
struct Section
var day: String
var classes: [String]
【讨论】:
以上是关于将 JSON 响应解析为结构的主要内容,如果未能解决你的问题,请参考以下文章