Karakuri.com

Fintechではたらくアプリケーションエンジニアの技術録

SwiftとiOSで定期的なバックグラウンド処理の実行は不可能なので諦めるべき

AndroidやWindowsではバックグラウンドで定期処理を実行することは比較的容易です。これと同様にiOSでも同じ機能を実装しようとすると問題に直面します。直面するというか、その機能はiOSでは実装できません。

iOSのバックグラウンド処理

UILocalNotificationで実行

UILocalNotificationを使えば、指定時間後にiOSからアプリの処理を実行させることができます。アプリがバックグランドでも、起動していなくても可能です。しかし、これはNotificationの通知からアプリを起動したときに呼ばれるメソッドです。Notificationの通知が発生したら呼び出されるわけではありません。起動中だと呼び出されるのですが。バックグラウンドで継続して定期的な処理を走らせることはできません。なお、iOS10以降ではUILocalNotificationはdeprecatedとなっており、UNNotificationRequestを使うように勧告されています。

Grand Central Dispatch(GCD)を使う

マルチスレッドで無限ループさせて定期実行すれば良いのではないかというアプローチです。しかし残念ながらバックグラウンドに移動するとOSがマルチスレッドの処理も止めてしまいます。また、これはAppleの想定している用途を逸脱しているので審査で落ちます。審査を通過できてもいつストアから削除されるか分かりません。

Background Fetchで実行

求めているものに最も近い機能に思えますが、そもそもAppleのプログラミングガイドで用途が定義されています。

  • アプリがバックグラウンドや終了してもダウンロードをバックグラウンドで継続する
  • アプリがバックグラウンドに移動しても音楽の再生を継続する

などが主な用途となります。それ以外の用途で使っているとOSが強制的に終了したり、審査に通らなかったりします。

バックグラウンド処理を巡った問題

Facebookが無音の再生でバックグラウンド処理を実装して問題に

2015年にはFacebookがこの機能を悪用し、無音の音源ファイルをバックグラウンドで再生し続けることでバックグラウンドの定期処理を実現していました。結局バレて大きな問題となりました。Facebookがこのような手段で実装するくらいですから、やはりiOSで定期的なバックグラウンド処理はデータのダウンロードなどサポートされている行為以外は諦めるしかないかと思います。
iphone-mania.jp