Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 리펙토링
- 클린 코드
- 리팩토링
- Refactoring
- clean architecture
- Protocol
- SWIFT
- UITextView
- tableView
- collectionview
- UICollectionView
- swiftUI
- MVVM
- 스위프트
- Xcode
- RxCocoa
- Observable
- ribs
- map
- swift documentation
- Human interface guide
- 리펙터링
- 애니메이션
- rxswift
- Clean Code
- HIG
- ios
- uiscrollview
- uitableview
- combine
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] json, codable, nestedContainer(keyedBy:forKey:), KeyedCodable로 중첩 모델 처리 방법 본문
iOS framework
[iOS - swift] json, codable, nestedContainer(keyedBy:forKey:), KeyedCodable로 중첩 모델 처리 방법
jake-kim 2022. 2. 9. 23:45* 기본적인 Codable, Decode, Encode 개념은 이곳 참고
* 관련 포스팅 글
- json, codable, nestedContainer(keyedBy:forKey:), Decoding 중첩 모델 처리 방법 (디코딩)
- json, codable, nestedContainer(keyedBy:forKey:), Encoding 중첩 모델 처리 방법 (인코딩)
- json, codable, nestedContainer(keyedBy:forKey:), KeyedCodable로 중첩 모델 처리 방법
중첩 모델을 flatten 모델로 정의 방법
{
"user_id": "jake",
"blog_info": {
"name": {
"first": "iOS 앱 개발 알아가기",
"second": "SwiftUI 앱 개발 알아가기"
}
}
}
- 이전까지는 blog_info.name.first에 접근하기 위해서 nested되지 않도록 nestedContainer(keyedBy:forKey:)를 사용
- 이전 포스팅 글 decoding, encoding 참고
struct MyModel { enum CodingKeys: String, CodingKey { case userID = "user_id" case blogInfo = "blog_info" } enum BlogInfoKeys: String, CodingKey { case name } enum NameKeys: String, CodingKey { case first case second } var userID: String? var blogName: String? } extension MyModel: Decodable { init(from decoder: Decoder) throws { let codingKeys = try decoder.container(keyedBy: CodingKeys.self) self.userID = try codingKeys.decode(String.self, forKey: .userID) let blogInfoKeys = try codingKeys.nestedContainer(keyedBy: BlogInfoKeys.self, forKey: .blogInfo) let nameKeys = try blogInfoKeys.nestedContainer(keyedBy: NameKeys.self, forKey: .name) self.blogName = try nameKeys.decode(String.self, forKey: .first) } } extension MyModel: Encodable { func encode(to encoder: Encoder) throws { var containerKeys = encoder.container(keyedBy: CodingKeys.self) try containerKeys.encode(self.userID, forKey: .userID) var blogInfoKeys = containerKeys.nestedContainer(keyedBy: BlogInfoKeys.self, forKey: .blogInfo) var nameKeys = blogInfoKeys.nestedContainer(keyedBy: NameKeys.self, forKey: .name) try nameKeys.encode(self.blogName, forKey: .first) } }
- nestedContainer를 일일이 써주는 것이 복잡하므로 KeyedCodable 프레임워크 사용
KeyedCodable
- git repo
- nested key를 쉽게 접근할 수 있는 기능
KeyedCodable 사용 방법
- cocoapods 사용
pod 'KeyedCodable'
- 모델 정의
- CodingKeys에서 CodingKey대신 KeyedKey 프로토콜 준수
- nested된 json에 접근할때는 dot. 으로 접근
import KeyedCodable /* { "user_id": "jake", "blog_info": { "name": { "first": "iOS 앱 개발 알아가기", "second": "SwiftUI 앱 개발 알아가기" } } } */ struct MyModel: Codable { enum CodingKeys: String, KeyedKey { case userID = "user_id" case blogName = "blog_info.name.first" } var userID: String? var blogName: String? }
- decode, encode를 사용하는 쪽에서도 매우 편리하게 사용 가능
import KeyedCodable let jsonSample = """ { "user_id": "jake", "blog_info": { "name": { "first": "iOS 앱 개발 알아가기", "second": "SwiftUI 앱 개발 알아가기" } } } """ // decoding let model = try? MyModel.keyed.fromJSON(self.jsonSample) print(model) // encoding let jsonString = try? model?.keyed.jsonString() print(jsonString)
- cf) KeyedCodable을 사용하지 않고 encode, decode 처리
// decoding guard let data = self.jsonSample.data(using: .utf8), let myModel = try? JSONDecoder().decode(MyModel.self, from: data) else { return } print(myModel.blogName) // encoding let sampleMyModel = MyModel(userID: "jake", blogName: "iOS 앱 개발 알아가기") guard let data = try? JSONEncoder().encode(sampleMyModel) else { return } let jsonString = String(data: data, encoding: .utf8) print(jsonString)
KeyOptions - json 스트링에 dot 키워드가 있는 경우 처리
- second.example에 접근 방법?
{
"user_id": "jake",
"blog_info": {
"name": {
"first": "iOS 앱 개발 알아가기",
"second.example": "SwiftUI 앱 개발 알아가기"
}
}
}
- var options: KeyOptions? 을 정의하여 사용
- CodingKeys에다 var options: KeyOptions?을 정의
- 아래 코드 의미는, `dot`키워드를 +로 쓴다는 의미이므로 이전에 dot으로 썼던 부분을 +로 사용하고, key값 내에서 dot 사용
- blog_info+name+second까지는 +로 접근하고, 실제 값 second.exmaple은 그대로 dot으로 이용
import KeyedCodable /* { "user_id": "jake", "blog_info": { "name": { "first": "iOS 앱 개발 알아가기", "second.example": "SwiftUI 앱 개발 알아가기" } } } */ struct MyModel: Codable { enum CodingKeys: String, KeyedKey { case userID = "user_id" case blogName = "blog_info+name+second.example" var options: KeyOptions? { switch self { case .blogName: return KeyOptions(delimiter: .character("+"), flat: .none) default: return nil } } } var userID: String? var blogName: String? }
* 전체 코드: https://github.com/JK0369/ExKeyedCodable
* 참고
'iOS framework' 카테고리의 다른 글
[iOS - swift] 2. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (Modal) (0) | 2022.02.24 |
---|---|
[iOS - swift] 1. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (개념, UIPenGestureRecognizer) (0) | 2022.02.23 |
[iOS - swift] UITextView placeholder 프레임워크 (UITextView+Placeholder) (0) | 2022.01.30 |
[iOS - swift] SkeletonView 스켈레톤 뷰 (로딩 뷰) (3) | 2022.01.19 |
[iOS - swift] DragDropCollectionView 프레임워크 (0) | 2022.01.14 |
Comments