🙆

NSNotification.Nameを拡張した定数がiOS 18から非推奨となっている

2024/07/25に公開

前提

  • 個別のアプリ開発どういうスタイルをとるかは自由だし好きにしたらいいと思う
  • 2024年7月時点で公開されているBetaのドキュメントについて言及している
    • この記事で言及していることは変わるかもしれない
      • おそらく変わらないと思うが念の為

はじめに結論

  • NSNotification.Nameの拡張で定数が用意されていたが、それは非推奨となっている
    • 念の為、みなさんがどうするかは好きにしたらいいからそれをどうかしたいわけじゃない
  • 非推奨の代替手段は結構前からすでに用意されていた

非推奨となっている

iOS 18となってNotification.Nameの定数がいくつも非推奨になっている。

これはかつて(というか今も)次のようにNSNotificationを使うための定数がNotification.Nameに拡張として用意されていて次のような感じで定義されている。

例は.AVCaptureDeviceSubjectAreaDidChangeを使う。

extension NSNotification.Name {
    public static var AVCaptureDeviceSubjectAreaDidChange: NSNotification.Name { get }

書くまでもないが利用例は次のようにする。

NotificationCenter.default
    .addObserver(
        self,
        selector: #selector(
            self.subjectAreaDidChange
        ),
        name: .AVCaptureDeviceSubjectAreaDidChange,
        object: videoDeviceInput.device
    )

省略せずに書くとNSNotification.Name.AVCaptureDeviceSubjectAreaDidChangeが使われているということ。そしてそれが非推奨となっている。

代替手段はAVCaptureDevice.subjectAreaDidChangeNotificationを使う。

https://developer.apple.com/documentation/avfoundation/avcapturedevice/1624619-subjectareadidchangenotification

これはiOS 5.0からあったらしい。
念の為例を示す。

NotificationCenter.default
    .addObserver(
        self,
        selector: #selector(
            self.subjectAreaDidChange
        ),
        name: AVCaptureDevice.subjectAreaDidChangeNotification,
        object: videoDeviceInput.device
    )

つまり?

  • NSNotification.Nameを拡張したやり方と同時にすでに別のやり方が混在していた?

考え

NSNotification.Nameを非推奨にし使わないやり方はより正しいように私には思える。

たとえば自分たちでアプリ開発をする際、今はもうモジュールを分割する。そして次のようなケースを考える。

  • CameraFeatureというモジュールを作る
    • CameraFeature内でsendする通知を作り、他モジュールでobserveしたい時
      • Notificationでの通知をしたい場合どうする?
        • やり方は二つ
          • やり方: CameraFeatureに定数おく
          • やり方: 共通のモジュールCommonに定数おく

これで、CameraFeatureに定数おくことを考えると、
CameraFeature.didShutterみたいなのを他モジュール側で通知することができる。
その利点は、どこからsendされているかを知りやすい。コードを探さなくてもモジュール名が使われているからわかりやすい。そしてCommonを使うのは最後の手段にできる。

同じことを別の視点で書くと、NSNotification.Nameというのは通知名をモデリングした型であり、その拡張としてドメイン知識を加えてしまうのは現代のスタイルとは合わないんじゃないかと思う。モジュール分割しない小さなアプリの場合はもちろんどうでもいい。

参考

コードはAppleのサンプルから
https://developer.apple.com/documentation/avfoundation/capture_setup/avcam_building_a_camera_app

しかし非推奨でも使っている...

Discussion