【Swift/Combine】catchメソッドの使い方!エラーを補足する方法

【Swift/Combine】catchメソッドの使い方!エラーを補足する方法

この記事からわかること

  • SwiftCombineフレームワーク
  • catchメソッド使い方
  • エラーごとに処理分岐する方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

公式リファレンス:Combine Framework

環境

catchメソッドの使い方

公式リファレンス:catchメソッド

func `catch`<P>(_ handler: @escaping (Self.Failure) -> P) -> Publishers.Catch<Self, P> where P : Publisher, Self.Output == P.Output

SwiftのCombineフレームワークのcatchエラーを補足し別のpublisherを流すメソッドです。catchを使用することで特定のエラーの場合は代替のストリームを提供し、特定のエラーの場合はそのままエラーを流すといったことができるようになります。

完了ハンドラーのクロージャーの引数から流れてくるerrorを参照することができ、最終的にpublisherを返します。

let publisher = PassthroughSubject<Int, MyError>()

let subscription = publisher
    .catch { error in
        // エラーが発生するとここが呼ばれる
        // クロージャーの引数から対象errorを参照できる
        // 後続のストリームに流すpublisherを返す
        Just(0)
    }
    .sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("完了")
        case .failure(let error):
            print("Error:", error)
        }
    }, receiveValue: { value in
        print("Value:", value)
    })

// パブリッシャーから値を送信
publisher.send(10)
publisher.send(completion: .failure(NSError(domain: "", code: 0, userInfo: nil)))

例えば上記のように実装した場合エラーが発生した場合はJust(0)を代わにストリームに流すため以下のような出力になります。

Value: 10
Value: 0
完了

エラーの値によって後続に流すストリームを分岐させる

Aエラーならそのまま、Bエラーなら別のpublisherを流したい」場合などエラーの値によって後続に流すストリームを分岐させるには以下のように実装すればOKです。

let publisher = PassthroughSubject<Int, MyError>()

enum MyError: Error {
    case someError1
    case someError2
}

let subscription = publisher
    .catch { error -> AnyPublisher<Int, MyError> in
        switch error {
        case .someError1:
            // エラーをそのまま返す
            return Fail(error: error).eraseToAnyPublisher()
        case .someError2:
            // 代替の値を返す
            return Just(0).setFailureType(to: MyError.self).eraseToAnyPublisher()
        }
    }
    .sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("完了")
        case .failure(let error):
            print("Error:", error)
        }
    }, receiveValue: { value in
        print("Value:", value)
    })

// パブリッシャーから値を送信
publisher.send(10)
publisher.send(completion: .failure(.someError1))

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index