-
Swift JSON 디코딩하는데 타입이 여러 데이터 타입으로 들어온다면?앱 개발자 2023. 9. 5. 22:06반응형
What if a field has multiple types? Here's a solution.
Error Message: typeMismatch
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "keywordList", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "monthlyPcQcCnt", intValue: nil)], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))
- 이 타입미스매치 에러를 보고 Int로 바꿨다. Int로 바꾸면 또 String으로 바꾸라고 에러 뜬다.
- 차분한 마음으로 데이터를 확인해보니 Int가 잘 들어오다가 "<10" 이런 String을 보내는 것이다!
문제의 JSON data: monthlyPcQcCnt 값을 보시라
//정상
{"relKeyword":"농협주택담보대출금리","monthlyPcQcCnt":550, ...
//에러
{"relKeyword":"후순위아파트담보대출대환","monthlyPcQcCnt":"< 10", ...Ask ChatGPT:
ChatGPT한테 물었다. 지금 유료 사용 기간이라 많이 물어봐야 한다.
Solution Code:
아래 코드를 복붙해서 바로 쓰면 된다.
enum 커스텀타입을 만들어 Int, String, Double 타입을 디코딩한다.
enum MyMultipleType: Codable { case int(Int) case string(String) case double(Double) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if let intValue = try? container.decode(Int.self) { self = .int(intValue) return } if let stringValue = try? container.decode(String.self) { self = .string(stringValue) return } if let doubleValue = try? container.decode(Double.self) { self = .double(doubleValue) return } throw DecodingError.typeMismatch(MyMultipleType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MonthlyPCQcCnt")) } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .int(let intValue): try container.encode(intValue) case .string(let stringValue): try container.encode(stringValue) case .double(let doubleValue): try container.encode(doubleValue) } } }
필요 시 Bool도 추가하면 된다.
데이터 구조체에 이렇게 적용하면 된다:
struct RelKwdStatResponseItem: Codable { let relKeyword: MyMultipleType let monthlyPCQcCnt: MyMultipleType let monthlyMobileQcCnt: MyMultipleType let monthlyAvePCClkCnt, monthlyAveMobileClkCnt: MyMultipleType let monthlyAvePCCtr, monthlyAveMobileCtr: MyMultipleType let plAvgDepth: MyMultipleType let compIdx: MyMultipleType enum CodingKeys: String, CodingKey { case relKeyword case monthlyPCQcCnt = "monthlyPcQcCnt" case monthlyMobileQcCnt case monthlyAvePCClkCnt = "monthlyAvePcClkCnt" case monthlyAveMobileClkCnt case monthlyAvePCCtr = "monthlyAvePcCtr" case monthlyAveMobileCtr, plAvgDepth, compIdx } }
To 독자, 더 좋은 아이디어가 있다면 공유해주세요!
아래 링크도 참고하세요!
반응형'앱 개발자' 카테고리의 다른 글
Quick Recap: Simplify Your YouTube Viewing with Instant Summaries (5) 2024.09.10 iOS 앱 출시 스크린샷 준비, 피그마&캔바 활용 (0) 2024.06.03 [Swift]여러 서버와 통신하기, URLSession 네트워킹 코드, 제네릭 함수로 만들어 재사용하기 (0) 2023.09.11 [Swift5] UISlider tap to change value: Tap on UISlider to Set the Value (0) 2023.08.22 IOS 앱 <NEW ME> 기획부터 출시까지 (0) 2022.07.22