iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
0
自我挑戰組

30 天了解 Swift 的 Combine系列 第 21

30 天了解 Swift 的 Combine: [21] Combine 的錯誤處理

  • 分享至 

  • xImage
  •  

Combine 中的 Error handling 可方便處理 throws 的錯誤拋出。

開始之前,先建立 Error 與 Function

enum DemoError: Error {case noReason}
func willThrow(_ nb:Int) throws -> String {
    throw DemoError.noReason
}

在不使用 Combine 的情形下,我們會這樣處理:

let result:String
do {
   result = try willThrow(1)
} catch {
    //handle Error
}

甚至有些時候會使用 try!/try? 來快速處理,而在套用 Combine 之後,我們可以用第 14 篇的失敗處理類型來處理

1. 單純使用 Sink

Just(1)
    .tryMap{ try willThrow($0)}
    .sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            fatalError()
        case .failure(let error):
            print(error)
        }
    }, receiveValue: {fatalError()})

2. 使用 Result

要使用 Result 時,需要一個幫助的

extension Publisher {
    typealias PublisherResult = Result<Output,Failure>
    
    func mapToResult() -> AnyPublisher<Result<Self.Output, Self.Failure>, Never>{
        self.map{PublisherResult.success($0)}
            .catch{Just<PublisherResult>(.failure($0))}
            .eraseToAnyPublisher()
    }
}

如此一來,就將上游元素轉化為 Result 的 enum

Just(1)
    .tryMap{ try willThrow($0)}
    .mapToResult()
    .sink{ result in 
        switch result {
            case .success(let element): fatalError()
            case .failure(let error): print(error)
        }
    }

3. 失敗執行指定指令

extension Publisher {
    func applyWhenFailure(receiveError: @escaping (Failure) -> Void) ->  Publishers.Catch<Self, Empty<Self.Output, Never>>{
       self.catch { error -> Empty<Output, Never> in
            receiveError(error)
            return Empty<Output,Never>()
        }
    }
}

以上是目前想到的錯誤處理方法。


上一篇
30 天了解 Swift 的 Combine: [20] Combine 好文分享: Custom publisher in UIControl
下一篇
30 天了解 Swift 的 Combine: [22] WWDC demo 解讀
系列文
30 天了解 Swift 的 Combine30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言