LoginSignup
1
0

More than 1 year has passed since last update.

[Swift] beginBackgroundTaskの使い方を間違えてスリープ時にアプリが落ちていた話

Last updated at Posted at 2022-12-09

概要

実行している処理をバックグラウンドでも継続したい場合は
UIApplication.shared.beginBackgroundTaskを使う方法があります。

公式より
https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtask

func beginBackgroundTask(expirationHandler handler: (() -> Void)? = nil) -> UIBackgroundTaskIdentifier

※ここのhandlerはバックグラウンドで実行できる時間が0になる直前で呼び出される。

発生した問題

自分が担当しているアプリではバックグラウンドに移行した時点でタスクを一時停止するため、handlerで実行する処理は何もないと思い、下記のようにしていた。

taskIdentifier = UIApplication.shared.beginBackgroundTask()

ところが、アプリのアップデート後に「処理がいつまで経っても終わらない」、「スリープから復帰するとアプリが最初の画面に戻る」などの声が出るようになった。
色々調べてみるとどうやらこのhandlerでタスクを明示的に終了しないとOS側からアプリが終了させられてしまうらしい。
バックグラウンドで処理が継続できる時間は環境により変わるらしいが、自分が測ったら3分~5分ほど。

現象としては下記のようだった。

  1. 長い処理があるのでユーザーが端末を放置
  2. 端末が自動スリープしてバックグラウンドに移行
  3. バックグラウンドで実行できる時間が0になり、OSからアプリが終了される
  4. ユーザーがアプリを起動するとスプラッシュの画面に戻っている

記事のタイトルは"アプリが落ちていた"にしたが正確にはOSにより終了させられていた。
ログにもyour app is terminated.みたいなものが出ていたと思います。たしか。

対応

対応としては下記のようにして明示的にタスクを終了させる。

taskIdentifier = UIApplication.shared.beginBackgroundTask {
    UIApplication.shared.endBackgroundTask(self.taskIdentifier)
}

それと、そもそもスリープに入ってしまうほど長い処理があるので処理中のみスリープさせないように対応した。

UIApplication.shared.isIdleTimerDisabled = true

最後に

そもそもhandlerの説明に書いてある。

A handler to be called shortly before the app’s remaining background time reaches 0. Use this handler to clean up and mark the end of the background task. Failure to end the task explicitly will result in the termination of the app. The system calls the handler synchronously on the main thread, blocking the app’s suspension momentarily.

アプリのバックグラウンドの残り時間が0になる直前に呼び出されるハンドラです。このハンドラを使用して、バックグラウンドタスクのクリーンアップと終了をマークします。タスクを明示的に終了させないと、アプリが終了してしまいます。システムはメインスレッド上で同期的にハンドラを呼び出し、アプリのサスペンドを一時的にブロックします。

ちゃんと説明書を読めってことですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0