이렇게 생긴 JSON포멧에서 distance
와 duration
만 파싱하려고 한다.
다른 변수들은 모두 필요가 없기 때문에, 저 둘의 상위 변수들에만 접근해서 추출하면 된다.
애플에서 소개된 방법으로는 최상위에서부터 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
이렇게 디코딩된 객체에서 단번에 접근할 수 있다.
'iOS' 카테고리의 다른 글
[따릉이 API] 서울시 열린데이터 광장에서 따릉이 API 활용해보기 (0) | 2021.11.24 |
---|