Last active
May 9, 2022 23:07
-
-
Save sgr-ksmt/d3b79ed1504768f2058c5ea06dc93698 to your computer and use it in GitHub Desktop.
JSONDecoder+keypath
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: 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