Swift Combineについて
Swift Combineは、iOSやmacOS、watchOSなどのAppleプラットフォーム向けのアプリ開発において、非同期処理やデータフローの操作を行うためのフレームワークです。この記事では、Swift Combineの基本的な使い方について解説します。
Combineの概要
Combineは、PublisherとSubscriberという2つの役割を持ったオブジェクトによって構成されます。Publisherは、値やイベントのストリームを生成し、Subscriberはそれを受け取り、処理を行うオブジェクトです。このストリームには、何らかの処理が加えられることによって、変換やフィルタリング、マージなどが行われます。
Combineの使い方
Combineを使用するには、まずPublisherとSubscriberを作成します。Publisherは、以下のようにして生成できます。
let publisher = Just("Hello, world!")
この例では、JustというPublisherを使用して、"Hello, world!"という値を1回だけ発行するストリームを生成しています。他にも、TimerやURLSessionなどの標準ライブラリや、自分でカスタムしたPublisherを作成することもできます。
一方、Subscriberは、以下のようにして生成します。
let subscriber = Subscribers.Sink<String, Error>(receiveCompletion: { completion in
// エラー処理など
}, receiveValue: { value in
print(value)
})
この例では、SinkというSubscriberを使用して、ストリームから受け取った値をコンソールに出力しています。他にも、AssignやFutureなどの標準ライブラリや、自分でカスタムしたSubscriberを作成することもできます。
そして、PublisherとSubscriberを結びつけることで、ストリームの生成と処理を行います。
publisher.subscribe(subscriber)
この例では、Justで生成したストリームを、Sinkで定義した処理に結びつけています。
Combineの操作
Combineには、ストリームの操作を行う演算子が用意されています。以下に代表的なものを示します。
マップ
let publisher = Just("123")
.map({ value in
return Int(value) ?? 0
})
publisher.subscribe(subscriber) // 123という文字列がInt型の123に変換される
フィルタリング
let publisher = [1, 2, 3, 4, 5]
.publisher
.filter({ value in
return value % 2 == 0
})
publisher.subscribe(subscriber) // 2, 4が出力される
マージ
let publisher1 = [1, 2, 3]
.publisher
let publisher2 = ["a", "b", "c"]
.publisher
let mergedPublisher = Publishers.Merge(publisher1, publisher2)
mergedPublisher.subscribe(subscriber) // 1, "a", 2, "b", 3, "c"が順番に出力される
コンバイン
let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<String, Never>()
let combinedPublisher = publisher1.combineLatest(publisher2)
.map({ value in
return "\(value.0) \(value.1)"
})
combinedPublisher.subscribe(subscriber)
publisher1.send(1)
publisher2.send("a")
publisher1.send(2)
publisher2.send("b")
publisher1.send(3)
publisher2.send("c")
この例では、PassthroughSubjectを使用して、2つのストリームを生成し、combineLatestでコンバインしています。それぞれのストリームから値が送信されるたびに、コンバインされたストリームが生成され、マップ演算子で文字列に変換されます。結果として、"1 a"、"2 b"、"3 c"が順番に出力されます。
Combineのエラー処理
Combineでは、ストリームの処理中にエラーが発生する可能性があります。そのため、Subscriberは、以下のようにしてエラー処理を行います。
let subscriber = Subscribers.Sink<String, Error>(receiveCompletion: { completion in
switch completion {
case .finished:
print("finished")
case .failure(let error):
print(error.localizedDescription)
}
}, receiveValue: { value in
print(value)
})
この例では、Sinkで定義したエラー処理を、receiveCompletionに記述しています。ストリームの処理が正常に終了した場合は、.finishedを、エラーが発生した場合は、.failureを受け取ります。エラー処理では、localizedDescriptionを使用して、エラーメッセージをコンソールに出力しています。
まとめ
Swift Combineは、非同期処理やデータフローの操作を行うためのフレームワークであり、PublisherとSubscriberという2つの役割を持ったオブジェクトによって構成されます。ストリームの生成や操作、エラー処理について、基本的な使い方を解説しました。