이렇게 생긴 JSON포멧에서 distanceduration만 파싱하려고 한다.

다른 변수들은 모두 필요가 없기 때문에, 저 둘의 상위 변수들에만 접근해서 추출하면 된다.

애플에서 소개된 방법으로는 최상위에서부터 depth를 하나씩 들어가면서 Container를 만들며 접근할 수 있다.

그런데, 상위 변수가 배열 형식일 경우에는 추가적으로 배열의 원소에 접근하는 작업이 필요하다.

검색을 해보면, nested array data, nested array, nested json과 같은 키워드로 결과가 나오는데

그 방법들을 모두 종합해서 가장 간단한 방법으로 구현 해 보았다.

아래 코드에서 보면 featuresContainer에 한번 접근 한 뒤에, 그 내부에서 featureContainer에 접근하는 것을 볼 수 있다.

struct MyORResponse: Decodable {
    let distance: Double?
    let duration: Double?

    init(from decoder: Decoder) throws {
        // 최상위 컨테이너에 접근한다.
        let rootContainer = try decoder.container(keyedBy: RootContainerKeys.self)

        // root > features
        var featuresContainer = try rootContainer.nestedUnkeyedContainer(forKey: .features)

        // root > features > feature
        let featureContainer = try featuresContainer.nestedContainer(keyedBy: FeatureKeys.self)

        // root > features > feature > properties
        let propertiesContainer = try featureContainer.nestedContainer(keyedBy: PropertiesKeys.self.self, forKey: .properties)

        // root > features > feature > properties > summary
        let summaryContainer = try propertiesContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .summary)


        // root > features > feature > properties > summary > duration, distance
        self.duration = try summaryContainer.decode(Double.self, forKey: .duration)
        self.distance = try summaryContainer.decode(Double.self, forKey: .distance)
    }

    private enum CodingKeys: String, CodingKey {
        case distance
        case duration
    }

    private enum RootContainerKeys: CodingKey {
        case features
    }

    private enum FeatureKeys: CodingKey {
        case properties
    }

    private enum PropertiesKeys: CodingKey {
        case summary
    }
}

위와 같이 모델을 작성한 경우에

let jsonData = """
{
    ...
}
""".data(using: .utf8)!

let result = try JSONDecoder().decode(MYORResponse.self, from: jsonData)

let distance = result.distance
let duration = result.duration

이렇게 디코딩된 객체에서 단번에 접근할 수 있다.

+ Recent posts