DEV Community

Khoa Pham
Khoa Pham

Posted on

How to easily parse deep json in Swift

JSONCodable is awesome, but sometimes we just need to quickly get value in a deepy nested JSON. In the same way I did for Dart How to resolve deep json object in Dart, let's make that in Swift.

See https://github.com/onmyway133/Omnia/blob/master/Sources/Shared/JSON.swift

public func resolve<T>(_ jsonDictionary: [String: Any], keyPath: String) -> T? {
    var current: Any? = jsonDictionary

    keyPath.split(separator: ".").forEach { component in
        if let maybeInt = Int(component), let array = current as? Array<Any> {
            current = array[maybeInt]
        } else if let dictionary = current as? JSONDictionary {
            current = dictionary[String(component)]
        }
    }

    return current as? T
}

So we can just resolve via key path

class JSONTests: XCTestCase {
    func test() {
        let json: [String: Any] = [
            "outside": [
                "object": [
                    "number": 1,
                    "text": "hello"
                ],
                "arrayOfObjects": [
                    [
                        "number": 2,
                        "text": "two"
                    ],
                    [
                        "number": 3,
                        "text": "three"
                    ]
                ],
                "arrayOfArrays": [
                    [
                        "one", "two", "three", "four"
                    ],
                    [
                        "five", "six", "seven"
                    ]
                ]
            ]
        ]

        XCTAssertEqual(resolve(json, keyPath: "outside.object.number"), 1)
        XCTAssertEqual(resolve(json, keyPath: "outside.object.text"), "hello")
        XCTAssertEqual(resolve(json, keyPath: "outside.arrayOfObjects.1.number"), 3)
        XCTAssertEqual(resolve(json, keyPath: "outside.arrayOfArrays.1.1"), "six")
    }
}

Original post https://onmyway133.github.io/blog/How-to-easily-parse-deep-json-in-Swift/

Oldest comments (0)