読者です 読者をやめる 読者になる 読者になる

ぺぷしのーげん

大企業からスタートアップに転職したアプリケーションエンジニアのブログ

挫折。iOSでは定期的にバックグラウンド処理を実行できない|Swiftプログラミング

f:id:hazakurakeita:20150726114647j:plain

ぱくたそ - フリー写真素材・無料ダウンロード

アプリが終了してもバックグラウンドで処理を定期的に実行するiPhoneアプリの開発を試みました。しかし、どれだけ調べてもアプリが起動していない状態で定期的な処理を実行する方法が出てきません。もう完全に挫折というか、諦めてしまいました。

 

なぜそのようなことができると思っていたか

5年ほど前にAndroidアプリを作った経験からです。当時、アプリが起動していなくても1秒ごとに処理を実行し、ウィジェットの画面を更新するアプリを作りました。Androidだとアプリの起動の有無に関わらず、バックグラウンドで処理を継続することは比較的容易というイメージがあります。これもそれもウィジェットという機能がAndroidにあるからなのかもしれませんが。

だからこそiOSでもできると思っていました。AndroidにできてiOSにできないはずはない。逆こそあれど、と。しかし、そこは簡単にはいかないのでした。。

voro.jpn.org

 

まず、UILocalNotificationでトライしてみる

UILocalNotificationを使えば、指定時間後にiOSからアプリの処理を実行させることができます。しかも、それはバックグランドにいても、アプリが起動していなくても可能だというのです。しかしこれは僕の勘違いでした。誰もがブログにバックグラウンド、アプリが起動してない状態からNotificationが走ったときは「このメソッドが呼び出されるよー」って書いています。しかし、それはNotificationの通知からアプリを起動したときに呼ばれるメソッドなのです。Notificationの通知が発生したら呼び出されるわけではないのです。起動中は呼び出されるんですけどね。。。

結果、どうなったかというとNotificationの通知が来て終わりです。表示された通知からアプリを起動すると、実装した処理が動き出します。これではダメ。裏で継続して定期的な処理を走らせることはできません。

swift-salaryman.com

 

Background Fetchを利用してみる

これが最も可能性がある方法です。名前からしてビンゴじゃないですか。しかし僕の考えは甘かった。このBackground Fetchを利用しても、バックグラウンド時は通常の通信はできません。Background Fetch用の通信方法で代替えできるならいいのですが、そもそも僕の開発しているアプリの通信部はライブラリ内です。APIを利用しているだけですから、その内部で何かが起きてもどうすることもできません。

更にバックグラウンドでの実行間隔もiOS任せというのが致命的。どうも最小値が20分とかだそうです。指定すればもっと早く実行されるという報告もありますが、それは最初の数回だけとか、最小値に設定していても気まぐれでしか実行されないとか。正直採用する気にはなりませんでした。

www.gaprot.jp

 

マルチスレッド(Grand Central Dispatch)を利用してみる

これも当初は可能性を感じた方法。しかしBackground Fetchと同様で通信に制限があるみたい。実際に動かしてみたところ、Gmail APIからデリゲートメソッドが呼び出されなかった。通信で失敗していると考えるのが妥当ですかね。ライブラリの内部はObjective-Cなので見る気もしません。。

更に、Grand Central Dispatchを使用してもバックグランド処理は180秒しか動作できないそうです。これでは話になりません。。。僕が作っているアプリは常時定期的に通信を行うアプリなので。

nanananande.helpfulness.jp

 

というわけで、アプリがフォアグラウンドにいるときだけ動作する仕様にしました。これって目覚ましアプリとかどうやって作るのかなーって思ってたんですが、確かに目覚ましアプリを作ったという記事が全然みつかりません(UILocalNotificationやRemote Notificationを使えばそれなりにはできます)。やっぱしバックグラウンド処理はiOSはできないのかなーというのが正直なところでした。誰か方法があればご教示ください。

 

2015/10/17追記

Facebookやらかしてくれたなwww

hazakurakeita.hatenablog.com

 

おしまい。