その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

【iOS7】プッシュ通知のバックグラウンド処理でハマったメモ

やりたかったこと:
プッシュ通知を受け取ったときにアプリを起動することなく(バックグラウンドで)APIを呼ぶ


これはおそらく「サイレントプッシュ通知(Silent Remote Notification)からの Background Fetch」の最も一般的な実装事例だと思うのですが、これがなかなかうまくいかず、試行錯誤しました。


最終的にはうまくいったのですが、そもそも何が原因だったのか、諸々の対策がどう効いて解決したのか、本質的なことはあまりわかっていません。とにかく最終的にうまくいった実装と参考にした記事をここにメモっておきます。


(どの記事にも書いてある application:didReceiveRemoteNotification:fetchCompletionHandler: を実装するとか、通知を送る側の話とか、従来通りのプッシュ通知実装と同じ手順とかはこの記事では省略しています。)

application:didFinishLaunchingWithOptions:の実装

[application unregisterForRemoteNotifications];
[application registerForRemoteNotificationTypes:
 UIRemoteNotificationTypeBadge|
 UIRemoteNotificationTypeAlert|
 UIRemoteNotificationTypeSound|
 UIRemoteNotificationTypeNewsstandContentAvailability];

[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];


ポイントは3点:


ポイント1: register〜 の前に unregisterForRemoteNotifications を呼ぶ

  • これを入れるまでは、バックグラウンド処理(didReceiveRemoteNotification)が呼ばれたり呼ばれなかったり(ほとんどのケースでは呼ばれない)だった
  • これを入れてから安定してバックグランド処理できるようになった


ポイント2: UIRemoteNotificationTypeNewsstandContentAvailabilityを追加する


(上記2点とも、下記記事の「トラブルシューティング」の項を参考にしました。)


ポイント3: setMinimumBackgroundFetchInterval: を呼ぶ

  • デフォルトは UIApplicationBackgroundFetchIntervalNever になってるらしい
  • UIApplicationBackgroundFetchIntervalMinimum をセットする


下記書籍の Background Fetch の項を参考にしました。


上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編
加藤 寛人 西方 夏子 藤川 宏之 鈴木 晃 高丘 知央
インプレスジャパン
売り上げランキング: 6,684

Capabilitiesの設定

Background fetchとRemote notificationsの両方ともにチェックを入れる

  • ほとんどの記事や書籍には、片方でよさそうなことを書いてある
  • 試行錯誤に疲れたので、最終的に両方のチェックが必須かどうかの検証はしていません。とにかく最後この状態でうまくいった、というだけ。

その他参考になった記事

その他のメモ

  • こちらの記事によると、なんかデバッグ時は下記のようにした方がよさそうに思ったけど、上述したunregister〜が有効で、この方法はあまり関係なかった(そもそも今回つくってたのはNewsstandアプリではない)
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NKDontThrottleNewsstandContentNotifications"];