Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
JSONDecoder+keypath
//: Playground - noun: a place where people can play
import UIKit
var json: String = """
{
"result": {
"persons": [
{
"name": "taro",
"age": 25
},
{
"name": "hanako",
"age": 23
}
],
"code": 0,
"flag": true
}
}
"""
struct PersonsResponse: Decodable {
struct Result: Decodable {
struct Person: Decodable {
let name: String
let age: Int
}
let persons: [Person]
let code: Int
let flag: Bool
}
let result: Result
}
let data = json.data(using: .utf8)!
let decoder = JSONDecoder()
var date = Date()
for _ in 0..<1000 {
do {
let _ = try decoder.decode(PersonsResponse.self, from: data)
} catch let error {
print(error)
}
}
print("1:", Date().timeIntervalSince(date))
extension JSONDecoder {
func decode<T: Decodable>(_ type: T.Type, from data: Data, keyPath: String) throws -> T {
let toplevel = try JSONSerialization.jsonObject(with: data)
if let nestedJson = (toplevel as AnyObject).value(forKeyPath: keyPath) {
let nestedJsonData = try JSONSerialization.data(withJSONObject: nestedJson)
return try decode(type, from: nestedJsonData)
} else {
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Nested json not found for key path \"\(keyPath)\""))
}
}
}
struct Person: Decodable {
let name: String
let age: Int
}
date = Date()
for _ in 0..<1000 {
do {
let _ = try decoder.decode([Person].self, from: data, keyPath: "result.persons")
} catch let error {
print(error)
}
}
print("2:", Date().timeIntervalSince(date))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment