ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Combine - MapError
    IOS/Combine 2024. 6. 22. 17:55

    오늘 소개할 에러 핸들링에 필요한 연산자로 .mapError Operator를 소개하겠습니다. 

    시작하기에 앞서, tryMap과 MapError로 에러 핸들링이 가능할 거 같은데요! 각 operator의 차이점이 있습니다 ㅎㅎ 먼저 map과 tryMap의 차이점을 다시 정립하고, mapError를 왜 사용하게 되는지 설명드리겠습니다.

     

    map vs tryMap

    Map은 지난 글에 이어 Publisher가 발행하는 Value를 특정한 형태로 다시 재발행하는 메커니즘, tryMap Operator의 경우 Error를 Throw 할 수 있는 Operator로 에러 발생 시 Subscriber에게 Completion 이벤트로 에러를 전달하게 됩니다.

    더보기

    다시보는 코드예제

    // Map Operator 코드예제
    [123, 4, 56].publisher
        .map { $0 * 2 }
        .sink(receiveValue: { print($0) })
    // Output: 246
    //         8
    //         112
    
    
    let arr = ["1", "abc", "56"]
    arr.publisher
        .compactMap { Int($0) }
        .sink(receiveValue: { print($0) })
    // Output: 1
    //         56
    
    
    
    ////////////////////////////////////////////////
    // tryMap Operator 코드예제
    func romanNumeral(from:Int) throws -> String {
        let romanNumeralDict: [Int : String] =
            [1:"I", 2:"II", 3:"III", 4:"IV", 5:"V"]
        guard let numeral = romanNumeralDict[from] else {
            throw ParseError()
        }
        return numeral
    }
    let numbers = [5, 4, 3, 2, 1, 0]
    cancellable = numbers.publisher
        .tryMap { try romanNumeral(from: $0) }
        .sink(
            receiveCompletion: { print ("completion: \($0)") },
            receiveValue: { print ("\($0)", terminator: " ") }
         )
    
    
    // Prints: "V IV III II I completion: failure(ParseError())"

    만약 에러 throwing 가능성이 있는 곳에 map operator를 쓰게 되면 다음과 같은 에러를 마주하게 됩니다.

    ‘Invalid conversion from throwing function of type '(_) throws -> _' to non-throwing function type '(String) -> _’

     

    .mapError

    tryMap의 경우 에러 방출 시 수신 Subscriber에 Completion 핸들링 시 정의되어 있는 에러 타입이 명시되지 않습니다. 최상위 조상 격인 Swift.Error 타입으로 자동 캐스팅되어 하위 Stream에게 전달되는데요, 이를 완료 이벤트 수신부에서 강제로 캐스팅해도 되지만, Combine에선 .mapError를 통해 에러 캐스팅을 최적화할 수 있습니다. 

    .mapError { $0 as? CustomError ?? .unknown }

    이렇게 상위 stream에서 에러를 캐스팅 하고 다시 하위 스트림에 방출하는 Operaotr로, 수신부에서 직접 에러핸들링 타입을 캐스팅할 필요없이 .mapError Operator를 통해 가능합니다. 즉, tryMap으로 방출되는 완료 이벤트는 Swift.Error 이벤트가 방출되는데, 이걸 이벤트 구독자 영역에서 에러를 캐스팅해서 사용할 게 아니라 방출 자체를 Swift.Error가 아닌 커스텀한 에러로 던지기 위해 .mapError를 사용한다는 것이지요.

     

     

    'IOS > Combine' 카테고리의 다른 글

    Combine - Future Publisher  (0) 2024.06.01
    Combine Operators 2(Replace)  (2) 2024.04.21
    Combine Operators 1 (transforming)  (0) 2024.04.13
    Combine Cancellable, subscription  (0) 2024.04.07
    Combine - Subscriber 2편  (0) 2024.03.30
Designed by Tistory.