[Combine] NotificationCenter を Combine と組み合わせて使う方法

Combine 的に、NotificationCenter を、observe する方法を説明します。

NotificationCenter

iOS アプリを作っていると、NotificationCenter からの通知に対して何かを実行したいということがあります。

デバイスの向きが変更されたときに、画面レイアウトを変更する必要があるときは、NotificationCenter から通知を受ける必要があります。

直近のケースでは、iOS デバイスの電源状態の変更に応じて、スクリーンロックの ON/OFF を切り替える必要がありました。

iOS のデバイスの電源状態は、以下のプロパティを参照することで確認できます。

電源状態を保持するプロパティ

Apple のドキュメントは、こちら

説明した記事は、こちら。
UIKit[iOS] 電源/バッテリー状態 と 画面ロック

AddObserver で observe

プロパティを参照するとその時点での状態が取得できるのですが、変更されたことを検知するためには、NotificationCenter を使う必要があります。

変更された時に通知を受け取る1つの方法として、NotificationCenter の addObserver メソッドを使って、通知を受け取る方法があります。

UIKit[UIKit] 電源状態の通知を受ける方法

この方法は、iOS 14 でも問題なく動きます。

NotificationCenter と新しいフレームワーク Combine を組み合わせることでも同様の機能を実現できます。

いわゆる Reactive っぽく実装する方法を説明します。

Combine で observe

Combine フレームワークと同時に、既存のフレームワークの多くに手が入れられ、Combine で使いやすくなっています。

NotificationCenter は、Combine 対応したフレームワークの代表と言えるかもしれません。

これまでの addObserver とは別に、Combine と組み合わせて使用するために、 NotificationCenter に publisher というメソッドが追加されました。

Apple のドキュメントは、こちら

指定した通知 (Notification) が発生すると、送信してくれる publisher です。

NotificationCenter publisher 使用例

上記のコードは、UIDevice の batteryStateDidChangeNotification が発生すると、sink に指定されている closure が実行されます。

注意
.sink の返り値である AnyCancellable は、ローカル変数に保持してはいけません。

この例では、クラスのインスタンスプロパティとして保持しています。

ローカル変数に保持してしまうとスコープから外れた時に破棄されてしまいます。(キャンセルされることになります)

まとめ:NotificationCenter と Combine を組み合わせて使う方法

NotificationCenter と Combine を組み合わせて使う方法
  • NotificationCenter.default.publisher で publisher を作成する
  • publisher を subscribe (sink 等) して、イベントを受け取り処理する
  • AnyCancellable は、クラスプロパティ等で保持していないと、メモリが破棄されたときにキャンセルされてしまうので、注意

Apple も同様の Article を出してます。

Swift 学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

Swift ポケットリファレンス

Swift を学んでも、プログラミング言語の文法を全て記憶しておくことは無理なので、ちょっとした文法の確認をするために、リファレンス本を手元に置いておくと便利です。

注意
Swift4 までしか対応していないので、理解して参照する必要があります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です