Home > AI > IOS > Foundation >

JSONDecoder

Example 1:

struct Postman: Decodable, Hashable {
    let valid: Bool
}

enum MyError: Error {
    case invalidServerResponse
}



var components = URLComponents()
components.scheme = "https"
components.host = "postman-echo.com"
components.path = "/time/valid"
components.queryItems = [
    URLQueryItem(name: "timestamp", value: "2016-10-10"),
]

let url = components.url
print(url!)


let task = URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
    guard error == nil else {
        print("Error \(error!)")
        return
    }
    guard let data = data else {
        print("No data found")
        return
    }

    do {
        let postman = try JSONDecoder().decode(Postman.self, from: data)
           DispatchQueue.main.async {
              print("good \(postman.valid)")
           }
        } catch let jsonError {
           print(jsonError)
        }
})


task.resume()

Example 2 (Apple Official): web data can have more attributes, but attributes in data model must appear in web data.

// data model 
struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
}


// web data
let json = """
{
    "name": "Durian",
    "points": 600,
    "description": "A fruit with a distinctive scent.",
    "title": "good",
    "id" : 9
}
""".data(using: .utf8)!

let product = try JSONDecoder().decode(GroceryProduct.self, from: json)

print(product.name) // Prints "Durian"

Example 3: data model can have extra attributes which are calculated from other attributes.

// data model
struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
    
    var poster: String {
        description.map{ return $0 + name}!
    }
}
 
 
// web data
let json = """
{
    "name": "Durian",
    "points": 600,
    "description": "A fruit with a distinctive scent.",
    "title": "good",
    "id" : 9
}
""".data(using: .utf8)!
 
let product = try JSONDecoder().decode(GroceryProduct.self, from: json)
 
print(product.name) // Prints "Durian"
print(product.poster)

Example 3: if the attribute poster is a predefined value, the code will have errors.

// data model
struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
    
    var poster: String = "poster"
}
 
 
// web data
let json = """
{
    "name": "Durian",
    "points": 600,
    "description": "A fruit with a distinctive scent.",
    "title": "good",
    "id" : 9
}
""".data(using: .utf8)!
 
let product = try JSONDecoder().decode(GroceryProduct.self, from: json)
 
print(product.name) // Prints "Durian"
print(product.poster)

Leave a Reply