プッシュ通知でcontent-available
フラグを使用してバックグラウンドフェッチをトリガーしています。 fetch
とremote-notification
UIBackgroundModes
を有効にしました。
これが私のAppDelegate.mで使っている実装です。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(@"Remote Notification Recieved");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"Looks like i got a notification - fetch thingy";
[application presentLocalNotificationNow:notification];
completionHandler(UIBackgroundFetchResultNewData);
}
アプリがバックグラウンドで実行されている場合、正常に動作します。(通知が受信され、アプリは「通知を受け取ったように見えます」というローカル通知をトリガーしました)。
ただし、アプリが実行されていないときおよびcontent-available
フラグ付きのPush通知を受信した場合、アプリは起動されませんおよびdidRecieveRemoteNotification
デリゲートメソッドは呼び出されません。
WWDCビデオマルチタスクの新機能(WWDC 2013の#204)は、次のことを示しています。
プッシュ通知がcontent-available
フラグ付きで受信されると、アプリケーションは「バックグラウンドで起動」されます。
アプリがバックグラウンドで起動しないのはなぜですか?
だから本当の問題は:
ユーザーがアプリを強制終了した後、iOSはバックグラウンドタスクを実行しますか?
UPDATE2:
あなたはcaniOS 8で導入された新しいPushKitフレームワークを使用してこれを達成することができます。PushKitはVoIPに使用されますが。だからあなたの用法はVoIP関連のためでなければならないそうでなければアプリ拒否のリスクがあります。 ( この答え を参照)。
UDPDATE1:
ドキュメントはiOS8に明確化されました。ドキュメントは こちら と読むことができます。これは関連する抜粋です。
アプリの着信リモート通知を処理するには、このメソッドを使用します。アプリがフォアグラウンドで実行されているときにのみ呼び出される
application:didReceiveRemoteNotification:
メソッドとは異なり、システムは、アプリがフォアグラウンドまたはバックグラウンドで実行されているときにこのメソッドを呼び出します。さらに、リモート通知のバックグラウンドモードを有効にした場合、システムはアプリを起動し(または中断状態から起動し)、プッシュ通知が到着したときにバックグラウンド状態にします。 ただし、ユーザーが強制終了した場合、システムは自動的にアプリを起動しません。そのような場合、システムが再び自動的にアプリを起動しようとする前に、ユーザーはアプリを再起動するかデバイスを再起動する必要があります。
これはWWDCのビデオでは明らかにされていませんでしたが、開発者フォーラムですばやく検索すると次のようになりました。
https://devforums.Apple.com/message/873265#873265 (ログインが必要です)
また、アプリスイッチャーからアプリを強制終了する(つまり、アプリを強制終了するためにスワイプアップする)場合、プッシュ通知やバックグラウンドフェッチに関係なく、OSがアプリを再起動することはありません。この場合、ユーザーは一度手動でアプリを再起動する必要があり、それ以降はバックグラウンドアクティビティが呼び出されます。 - pmarcos
その記事はAppleの従業員によるものだったので、私はこの情報が正しいと信じることができると思います。
そのため、アプリがアプリスイッチャーから(スワイプアップで)強制終了されると、スケジュールされたバックグラウンドフェッチであってもアプリは起動されません。
「スキームの管理」でターゲットの起動設定をWait for <app>.app to be launched manually
に変更できます。これにより、application: didReceiveRemoteNotification: fetchCompletionHandler:
にブレークポイントを設定し、プッシュ通知を送信してバックグラウンド起動をトリガーすることでデバッグできます。
問題が解決するかどうかはわかりませんが、現時点ではデバッグに役立つ可能性があります。
答えはYESですが、「Background Fetch」や「Remote notification」を使用しないでください。 PushKitはあなたが望む答えです。
まとめると、ios 8の新しいフレームワークであるPushKitは、視覚的な警告なしに静かにあなたのアプリをバックグラウンドで起動することができる新しいPush通知メカニズムです。アプリスイッチャーから。
アップルからのPushKitリファレンス:
PushKitフレームワークは、iOSアプリがリモートサーバーからプッシュを受け取るためのクラスを提供します。プッシュには、標準とVoIPの2つのタイプがあります。標準プッシュは、以前のバージョンのiOSと同じように通知を配信できます。 VoIPプッシュは、ユーザーに通知を表示する前にプッシュのオンデマンド処理を実行するためにVoIPアプリに必要な標準プッシュの上に追加機能を提供します。
この新機能をデプロイするには、このチュートリアルを参照してください。 https://zeropush.com/guide/guide-to-pushkit-and-voip - 私は自分のデバイスでそれをテストしました、そしてそれは動作します予想通り。
実際にバックグラウンドフェッチをテストする必要がある場合は、schemeで1つのオプションを有効にする必要があります。
別の方法でそれをテストすることができます:
これはこの新機能についての完全な情報です: http://www.objc.io/issue-5/multitasking.html
私は何日もこれのさまざまな変種を試してきました、そしてユーザーが殺すようにスワイプしたときでさえ、私はそれがバックグラウンドでアプリを再起動させる日を考えました。
以前とは動作がまったく異なるのは残念です。 iOS 6では、揺れ動くようなアイコンからアプリを削除しても、SLCのトリガーが表示されたときにアプリは再起動します。今、あなたが強打で殺しても、それは起こりません。
これは別の振る舞いです。ユーザーが、iOS 6でそれを殺したとしても、私たちのアプリから有用な情報を入手し続けるでしょうが、今はそうしません。
ユーザーがアプリを強制終了しても、アプリを開くのをやめて、まだ通知操作が行われていることが予想される場合は、今すぐこのアプリを開くようにユーザーに注意を促す必要があります。ユーザーがアプリをスワイプしても明らかにならないのではないかと心配です。結局のところ、彼らは基本的にクリーンアップしているか、最小化されて表示されているアプリを並べ替えたいと思うかもしれません。
これはあなたを助けるかもしれません
ほとんどの場合、システムはアプリケーションがユーザーによって強制終了された後に再起動しません。ただし、iOS 8以降ではユーザーが強制終了した後に再起動されます。ただし、それ以外の場合は、システムによってアプリがバックグラウンドで自動的に起動される前に、ユーザーがアプリを明示的に起動するかデバイスを再起動する必要があります。デバイスでパスワード保護が有効になっていると、ユーザーが最初にデバイスのロックを解除するまで、システムはバックグラウンドでアプリを起動しません。