Codable TypeMismatch 오류

2023. 12. 1. 12:02·Study/🚨 TroubleShooting

문제

커서 기반 페이지네이션 구현 중 next_cursor 값을 디코딩하면서 오류가 발생하였다.

next_cursor로 다음 페이지를 계속해서 요청하다가 더이상 다음 데이터가 존재하지 않으면 0값을 가지고 온다.

응답 결과 디코딩 시 결과 값을 담을 구조체에 next_cursor 값의 타입이 두가지 경우가 존재하는 것이다.

 

Untitled.pngUntitled.png

String 값으로 정의하였더니 다음과 같은 TypeMismatch 오류가 발생하였다.

Swift.DecodingError.typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "next_cursor", intValue: nil)], debugDescription: "Expected to decode String but found number instead.", underlyingError: nil))

 

해결

이러한 문제를 해결하기 위해서는 결과 값이 제대로 디코딩이 되는지 확인 후 값을 변경시켜주는 방법이 있다. 응답 받을 구조체 모델에서 init 구문을 통해 확인하고 값을 변경해줄 수 있다.

1. init(decoder: )를 통해 타입 체크하기

Untitled.png

CodingKey로 구성된 키 값을 사용하여 값을 디코딩할 때 문제가 발생하면 typeMismatch 에러를 throw를 하도록 정의되어있다.

struct ReadResponse: Codable {
    let data: [Post]
    var nextCursor: String

    enum CodingKeys: String, CodingKey {
        case data
        case nextCursor = "next_cursor"
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.data = try container.decode([Post].self, forKey: .data)
        if let nextCursor = try? container.decode(String.self, forKey: .nextCursor) {
            self.nextCursor = nextCursor
        } else {
            self.nextCursor = "0"
        }
    }
    
}

try 문을 통해 String 타입으로 디코딩이 되는지 확인하고 String으로 변환되지 않았을 때 String타입의 “0”을 저장하도록 구현하였다.

이 방법의 단점이라하면 모든 값들을 디코딩을 해야한다는 문제가 있다.

디코딩 해야하는 요소들의 개수가 많고, 타입 체크를 해야하는 요소가 적다면 불필요한 코드를 많이 작성하게 된다.

이러한 부분을 해결하기 위해 PropertyWrapper를 사용하여 하나의 요소만 확인하는 방식을 사용하였다.

2. @PropertyWrapper & .singleValueContainer()

@propertyWrapper
struct NextCursorType {
    var wrappedValue: String
}

extension NextCursorType: Codable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let nextCursor = try? container.decode(String.self) {
            wrappedValue = nextCursor
        } else {
            wrappedValue = "0"
        }
    }
}

NextCursorType이라는 PropertyWrapper를 생성하였다.

위에서 init을 통해 디코딩 한 것과 비슷한 방식이다.

 

Untitled.png

단일 값을 디코딩하는 메서드이고, container와 마찬가지로 에러 발생 시 typeMismatch를 thorw하도록 정의되어 있다.

wrappedValue의 값을 체크하여 String 타입이 아닐 시 String 타입의 “0”을 wrappedValue 값으로 설정한다.

struct ReadResponse: Codable {
    let data: [Post]
    @NextCursorType var nextCursor: String

    enum CodingKeys: String, CodingKey {
        case data
        case nextCursor = "next_cursor"
    }
    
}

길었던 init구문은 필요가 없게 되었고, NextCursorType이라는 PropertyWrapper를 통해 간단하게 값을 변경할 수 있다!!

'Study > 🚨 TroubleShooting' 카테고리의 다른 글

[iOS/RxSwift] API 통신에서 Single과 Observable  (0) 2023.11.14
[iOS/Swift] Modal Style과 LifeCycle  (0) 2023.09.07
테이블 뷰 셀 오류  (1) 2023.08.03
'Study/🚨 TroubleShooting' 카테고리의 다른 글
  • [iOS/RxSwift] API 통신에서 Single과 Observable
  • [iOS/Swift] Modal Style과 LifeCycle
  • 테이블 뷰 셀 오류
김졀니
김졀니
🍎 iOS 개발
  • 김졀니
    졀니의 개발 공부✨
    김졀니
  • 전체
    오늘
    어제
    • 분류 전체보기
      • iOS
        • Swift
        • UIKit&SwiftUI
        • RxSwift&Combine
        • WWDC
      • Study
        • 🚨 TroubleShooting
        • 🌱 SeSAC
  • 블로그 메뉴

    • 홈
    • Github
  • 인기 글

  • 최근 글

  • 태그

    displayPriority
    concurrency
    @PropertyWrapper
    mapkit
    kingfisher header
    traits
    RxSwift
    이미지 캐싱
    ios
    Realm
    observable
    Swift
    위치 권한
    ReactorKit
    동시성프로그래밍
    FileManager
    mainactor
    pointfree
    Sendable
    CLLocation
    actor
    Drawing Cycle
    swift concurrency
    OperationQueue
    의존성 주입
    clipstobounds
    layoutIfNeeded
    인앱리뷰
    swiftdata
    wwdc23
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
김졀니
Codable TypeMismatch 오류
상단으로

티스토리툴바