SilentNotificationとBackgroundFetchについて
iOS7でアプリがバックグラウンドで動作できるAPIがいくつか追加されました
BackgroundFetch
これを有効にするとOSが定期的に良いタイミングでバックグラウンドでアプリを起動させ、AppDelegateの
application:performFetchWithCompletionHandler:
を実行してくれます。
このメソッドの中で30秒間自由に動くことができます。もちろんファイルのダウンロードやデータベースの更新も可能です。
良いタイミングというのは、ユーザのアプリ起動履歴をOSが監視し、アプリの起動時間帯などを考慮し適切なタイミングで呼ばれるということです。また、ユーザが明示的にAppSwitcherから削除した場合はこのメソッドは呼ばれなくなります。 したがって開発者が時間を決めて定期的にアプリを動かしたいというニーズは満たされません。おまけ程度に考えておきましょう。
SilentNotification
今までのRemoteNotification(push通知)では、受信した際にアプリが起動していなければ必ずロック画面などに通知されていました。 SilentNotificationではロック画面や通知センターに通知を表示することなく、アプリに対してだけ「ひっそりと」通知を行うことが可能になったということです。 ユーザにはpush通知が届いたことはわかりませんから、受信した際にひっそりと最新の情報をダウンロードしたりできるわけです。
注意したいのは、Silentでない通常のpush通知でも、受信した際に最新の情報をダウンロードしたりすることができることです。
push通知を受信後にバックグラウンドで動ける通知のことをSilentNotificationだと考えている方が多いようですが、そうではありません。単にユーザに気づかせないpush通知がSilentNotificationです。 push通知受信後にバックグラウンドで動くことができるのは
content-available:1
というフラグが立っているpush通知です。Silentか通常かは関係ありません。
content-available:1というフラグが立っており、アプリ側で設定をしていれば Silentも通常も受信後に
application:didReceiveRemoteNotification:fetchCompletionHandler:
が呼ばれ30秒間動くことができます。 content-availableフラグがなければこのメソッドが呼ばれることはありません。
application:didReceiveRemoteNotification:
が呼ばれます。こちらのメソッドの場合バックグラウンドで動くことはできません。
ちなみにこのSilentNotificationはAPNS側で制限がかかるようで、何度も送れないようです。
content-available:1のSilentNotificationと通常のpush通知の例として以下のようなことが考えられます。
例えば、天気予報アプリで最新の情報があることをpush通知で知らせます。しかし天気の最新情報ごときで毎回ユーザに通知していたらアンインストールされます。 そこでSilentNotificationの登場です。ユーザには通知されませんが、アプリに通知されますので、バックグラウンドでひっそりと最新情報を取得し、画面を更新しておくことができます。そうすれば、次にユーザが起動した際にはすでに最新情報が見ることができます。
通常のpush通知の例として、Twitterの@tweetです。こちらはユーザに届いたことをすぐに通知すべきです。さらにユーザがアプリを起動するまでにその内容をダウンロードしておきたいです。そういった場合にはSilentNotificationではなく、通常のpush通知を使いましょう。
どちらも最新情報のダウンロードを取得することが主な目的だと思いますが、アプリはバックグラウンド状態で完全に起動しているため、基本的にはなんでもできるはずです。状態としてはTask Completionと同じですね。