I just learned Argo basics and was able to decode 99% of my JSONs in production. Now I am facing the following structure (the keys like "5447" and "5954" are dynamic) and need help:
{
"5447": {
"business_id": 5447,
"rating": 5,
"comment": "abcd",
"replies_count": 0,
"message_id": 2517
},
"5954": {
"business_id": 5954,
"rating": 3,
"comment": "efgh",
"replies_count": 0,
"message_id": 633
}
}
The typical sample of Argo decoding is like:
struct User {
let id: Int
let name: String
}
for JSON structure (keys are fixed "id" and "name"):
{
"id": 124,
"name": "someone"
}
using something like this:
extension User: Decodable {
static func decode(j: JSON) -> Decoded<User> {
return curry(User.init)
<^> j <| "id"
<*> j <| "name"
}
}
However the data structure I need to parse doesn't fit the example.
UPDATE: using Tony's first implementation with a small modification in the last line, I got my job done. Here is the complete working code:
Business.swift:
import Argo
import Curry
import Runes
struct Business {
let businessID: Int
let rating: Double?
let comment: String?
let repliesCount: Int?
let messageID: Int?
}
extension Business: Decodable {
static func decode(_ json: JSON) -> Decoded<Business> {
let c0 = curry(Business.init)
<^> json <| "business_id"
<*> json <|? "rating"
return c0
<*> json <|? "comment"
<*> json <|? "replies_count"
<*> json <|? "message_id"
}
}
Businesses.swift
import Argo
import Runes
struct Businesses {
let businesses: [Business]
}
extension Businesses: Decodable {
static func decode(_ json: JSON) -> Decoded<Businesses> {
let dict = [String: JSON].decode(json)
let arr = dict.map { Array($0.map { $1 }) }
let jsonArr = arr.map { JSON.array($0) }
return Businesses.init <^> jsonArr.map([Business].decode).value ?? .success([])
}
}