anz blog

Swift6 環境下でプッシュ通知許可をリクエストするとクラッシュする

2025-02-13 #Swift

Strict Concurrency Checking を Complete に設定したうえでエラーやワーニングを解消しきったので、意気揚々とSwift6に切り替えてアプリ起動したのだけれどクラッシュしてしまうという現象に遭遇。
原因を探ったところクラッシュしているスレッドのIDが apns 系だったので、そこらをきっかけに調べたところ見事にプッシュ通知の許可を求める際に書き方次第ではクラッシュするというものでした。

詳細

Swift 6 に切り替えて、アプリを起動するととあるタイミングで有無も言わずにアプリがクラッシュするという不具合が発生。
エラーログとかそこらを見てみると、どうもプッシュ通知許可周りがあやしいというところでそこらに絞って調べたところ、書き方次第ではプッシュ通知の許可を求める際にクラッシュすることが反映。
そのクラッシュする書き方というのがこちら

UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { granted, error in
    // なにか
}

こういう感じで許可をもとめているとクラッシュします。
ちなみにビルドエラーはもちろんワーニングなんかもないので、実行しない限りは気付けないタイプの厄介なエラーです。

回避策

この許可をもとめるものは上記の例のようなコールバック式もあるけれど非同期実行もあるのでそちらを使えばOK

let granted = try await UNUserNotificationCenter.current().requestAuthorization(options: [.alert])

こちらを使えばクラッシュせずに許可をもと得ることができるようになる。
参考に記載しておく Apple Forum の方には詳しく説明しているコメントもあるので気になる場合みてみるといい。

同様のほか問題

この許可まわりコールバック方式を使っているとクラッシュするということでもう1つ同じ書き方をしているものがあったので確認したところ、こちらも同様にクラッシュしました。それがトラッキング許可を求めるところです。

ATTrackingManager.requestTrackingAuthorization {
    // なにか
}

これも実行時にクラッシュし、回避策も同様に非同期タイプのものに乗り換えるだけ。
こういうのがあるの分かっているはずなので、Swift 6 に切り替えてコールバックの方使っていたらビルドエラーなりワーニングを出るようにしてほしさある。
他にもなにかありそうで不安になる。

参考