iOS13以降で使用できる”Combine”とは?

SWIFT

最近仕事でコードのリファクタリングを皆で行っているのですが、外注でお願いしている優秀なエンジニアがOpenCombineというフレームワークを導入してくれました。

これはCombineというフレームワークをiOS13以前でも使用可能にするもののようなのですが、使用方法が全然わからず。

というか、Combine自体が全く未知でした。。。

ということで、今回はCombineとは何かについてさわりだけまとめていこうと思います!

今回参考にしたのはこちら

Swiftでいこう! - "Combine"とは?|donguri|note
奥が深そうなCombineです。 Combine 最初の一歩 - Toyship.org WWDC2019で紹介されたCombineはSwiftで使えるasync frameworkです。 iOS13以上でしか使 www.toyship.org はじ...
[Swift] はじめてのCombine | Apple製の非同期フレームワークを使ってみよう | DevelopersIO
こんにちは。きんくまです。 今回はiOS13から使えるようになったCombineをやってみました! Combineって何? イベントの発行と購読をすることができるフレームワークです。 非同期処理の中で使えばスッキリと書く …

Combineとは

Combineを一言でいうと、イベントの発行と購読をすることができるフレームワークです。

イベントの…発行?購読?って思いましたが、要するにあるイベントを出力したら任意のタイミングで値を受け取ることができるという解釈でいいと思います。

これまでのSwiftだと、どうしてもコールバック地獄になることがあったのですが、これが解消されるわけですね。

シンプルな使用方法

登場人物は以下の三者。

Publisher : イベントを発行する人

Subscriber : イベントを受け取って処理する人

Operator : 流れてくる値を加工する人

以上の三者がPublisher -> Operator -> Subscriber とベルトコンベアのように処理をしていくのだそう。

今回はPublisherとSubscriberの2者に絞ってシンプルなコードを書いてみた。

//まずCombineフレームワークをインポート
import Combine
import Foundation

//値を出力する
let publisher = Just(100)

//値を受け取る
let subscriber = Subscribers.Sink<Int, Never>(
    receiveCompletion:
        {completion in
            switch completion {
            case .failure(let error):
                print(error.localizedDescription)
            case .finished:
                print("終了")
            }
        }
    , receiveValue: {value in
        print(value)}
)

//実行
publisher.subscribe(subscriber)

//結果
100
終了

こちらを解説。

Publisher側について

publisher(イベント発行側)がイベントを発行するには、JustやFutureというメソッドがあるみたいです。

Just : 同期的にイベントを発行

Future : 非同期でイベントを発行

今回はするイベントを発行したいのでJustで100を出力します。

Subscriber側について

Sinkというメソッドで値を受け取ります。

上記では、エラー処理を書いていますが、基本的にJustで送られたイベントはエラーにならないので省略することも可能。

受け取ったらvalueをプリントし、完了したら”終了”と出力されます。

以上までの処理をめっちゃ短くすることもできるようです。

こんなかんじ↓

Just(100).sink(receiveValue: { value in
    print(value)
})

//結果
100

今回はシンプルなことしかしていませんが、これを活用できるようになるとサーバーとのデータのやり取りをわかりやすく表現できたり保守性が上がりそうだと感じました!

OpenCombineなどについても今後もっと詳しく調べていこうと思います!

コメント

タイトルとURLをコピーしました