从 JSON 响应中解析两个不同对象的数组
Posted
技术标签:
【中文标题】从 JSON 响应中解析两个不同对象的数组【英文标题】:parsing two different object's array from JSON response 【发布时间】:2018-04-24 12:39:11 【问题描述】:我正在尝试解析 JSON 数据 .. 我知道如何为一个对象数组执行此操作 .. 但我不知道如何为具有两个不同对象数组的响应执行此操作 ..
例如这是 JSON:
"shifts": [
"id": 4,
"region": "Eastren",
"city": "Khobar",
"nationality": "1",
"id_service": 2,
"shift_date": "2018-04-05",
"shift_type": "night",
"weekday": "sunday",
"quantity_staff": 8,
"lead_hours": 2,
"created_at": "2018-04-23 11:46:20",
"updated_at": "2018-04-24 08:46:14",
"deleted_at": null
,
"id": 5,
"region": "Eastren",
"city": "Khobar",
"nationality": "Phili",
"id_service": 2,
"shift_date": "2018-04-04",
"shift_type": "night",
"weekday": "sunday",
"quantity_staff": 8,
"lead_hours": 2,
"created_at": "2018-04-23 11:47:25",
"updated_at": "2018-04-23 12:53:05",
"deleted_at": "2018-04-23"
],
"prices": [
"id": 1,
"id_service": 2,
"nationality": "Phili",
"price": 150,
"created_at": "2018-04-23 11:43:40",
"updated_at": "2018-04-23 11:43:40",
"deleted_at": null
]
它有两个对象数组..班次和价格..如何解析每个对象?
我的功能:
func GetShiftsAndPrices(id: Int)
let todosEndpoint: String = "my link"
guard let todosURL = URL(string: todosEndpoint) else
print("Error: cannot create URL")
return
var todosUrlRequest = URLRequest(url: todosURL)
todosUrlRequest.httpMethod = "POST"
todosUrlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
let newTodo: [String: Any] = ["id_service": id]
let jsonTodo: Data
do
jsonTodo = try JSONSerialization.data(withJSONObject: newTodo, options: [])
todosUrlRequest.httpBody = jsonTodo
catch
print("Error: cannot create JSON from todo")
return
let session = URLSession.shared
let task = session.dataTask(with: todosUrlRequest)
(data, response, error) in
guard error == nil else
print("error calling POST on /public/api/login_customer")
print(error!)
return
guard let responseData = data else
print("Error: did not receive data")
return
// parse the result as JSON, since that's what the API provides
do
//WHAT SHOULD I DO HERE?
print("Success!")
catch
print("error parsing response from POST")
return
task.resume()
我有班次和价格课程 .. 并且知道如何在单独响应时获得每个课程 .. 比如:
班次:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let shifts1 = try decoder.decode([Shifts].self, from: responseData)
var shifts = [Shift]()
for shift in shifts1
let newshift = Shift(id: shift.id, region: shift.region, city: shift.city, nationality: shift.nationality, idService: shift.idService, shiftDate: shift.shiftDate, shiftType: shift.shiftType, weekday: shift.weekday, quantityStaff: shift.quantityStaff, leadHours: shift.leadHours)
shifts.append(newshift)
let userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: shifts)
userDefaults.set(encodedData, forKey: "shifts")
userDefaults.synchronize()
let decoded = userDefaults.object(forKey: "shifts") as! Data
let decodedShift = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Shift]
for shift in decodedShift
print(shift.id)
价格:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let prices1 = try decoder.decode([Prices].self, from: responseData)
print("1")
var prices = [Price]()
for price in prices1
let newprice = Price(id: price.id, idService: price.idService,nationality: price.nationality, price: price.price)
print("2")
prices.append(newprice)
print(newprice.nationality)
let userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: prices)
userDefaults.set(encodedData, forKey: "prices")
userDefaults.synchronize()
let decoded = userDefaults.object(forKey: "prices") as! Data
let decodedPrice = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Price]
for price in decodedPrice
print(price.nationality)
如何在一个 JSON 响应中同时解析它们。我是新手。有人可以告诉我该怎么做吗?
【问题讨论】:
您可以创建一个容器对象,将班次和价格作为变量并制作 2 个映射,然后每个映射都将映射到它自己的类中 @ΒασίληςΔ。这该怎么做?对不起,我是这个 x_x 的新手 你没有两个数组;你有一本字典。所以这是一个可解码的结构。班次和价格是可解码的结构。这对于三个 Decodable 结构来说是微不足道的。根本不要使用 JSONSerialization。 @matt 那怎么办呢?你能举个例子吗? 【参考方案1】:使用伞形结构
struct Root : Decodable
let shifts : [Shift]
let prices : [Price]
还有两种不同的班次和价格结构:
struct Shift : Decodable
let id: Int
let region, city, nationality : String
let idService : Int
let shiftDate, shiftType, weekday : String
let quantityStaff, leadHours : Int
let createdAt, updatedAt : String
let deletedAt : String?
struct Price : Decodable
let id, idService : Int
let nationality : String
let price : Int
let createdAt, updatedAt : String
let deletedAt : String?
解码 JSON 写入
do
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder .decode(Root.self, from: responseData)
print(result.prices)
print(result.shifts)
catch print(error)
我还建议将shiftType
和weekday
等键直接解码为enum
,例如
enum ShiftType : String, Decodable
case day, night
struct Shift : Decodable
let id: Int
...
let shiftType : ShiftType
...
【讨论】:
【参考方案2】:let shifts = responseJson.valueFor(key:"shifts") as? [String] ?? []
let prices = responseJson.valueFor(key:"prices") as? [String] ?? []
print("\(shifts) and \(prices)")
【讨论】:
什么是 responseJson? 是json解析后得到的响应 此帖子已被标记为低质量。 @SuganyaMarlin 请尝试解释 OP 在哪里遇到问题以及如何解决它,仅发布代码对寻求解释的更大社区没有帮助以上是关于从 JSON 响应中解析两个不同对象的数组的主要内容,如果未能解决你的问题,请参考以下文章