web-dev-qa-db-ja.com

ユーザーまたはサーバーの介入なしにiOSで中断されたアプリをウェイクアップする方法はありますか

「大幅変更位置情報サービス」を使用せずにiOSアプリをウェイクアップする方法はありますか?

サーバーまたはユーザーの介入なしにアプリをウェイクアップする必要があります。

ILocalNotification-ユーザーとサーバーの介入が必要になるため、機能しません。

サイレントプッシュ通知-ローカル通知をサイレントプッシュ通知として送信できないため、機能しません。これらはサーバーによってのみ送信できます。つまり、サーバーの介入が必要になります。

Background Fetch-トリガー時間が保証されていないため機能しません。

何か不足していますか?

16
Haris Farooqui

編集:質問を調整して、「ユーザーまたはサーバーの介入なし」と明示的に述べました。

いいえ、設計上私が知っている限りでは、iOSは将来の決まった時間にアプリを起動する明示的な方法を提供しません。バックグラウンドで長時間実行されるタスクを継続し、更新されたコンテンツを日和見的に取得し、必要に応じてアプリを再度開くようにユーザーに通知し、必要に応じて最初の2つにサイレントプッシュ通知を促すことができます。

上記の3つのオプションに関するヒントを次に示します。

UILocalNotification

最も簡単な方法は、 UILocalNotifications を一度にスケジュールすることですが、アプリを起動するには通知を操作する必要があります。これはあなたが望むものではないかもしれません。

サイレントプッシュ通知

IOS 7以降の別のオプションは、content-availableまたはサイレントプッシュ通知です。この種の通知用に特定のペイロードを設定し、アプリに適切なUIBackgroundMode値が設定されている場合、サイレントでアプリに配信されます。

ペイロードは次のようになります。

{
    "aps" : {
        "content-available" : 1
    },
    "content-id" : 42
}

また、特定のデリゲートメソッドを使用して、アプリのデリゲートで受信します。

- (void)         application:(UIApplication *)application 
didReceiveRemoteNotification:(NSDictionary *)userInfo 
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification userInfo is %@", userInfo);

    NSNumber *contentID = userInfo[@"content-id"];
    // Do something with the content ID
    completionHandler(UIBackgroundFetchResultNewData);
}

その後、この機会にコンテンツをダウンロードしたり、必要に応じてアプリをすばやく更新したりできます。このアプローチの詳細については、UIBackgroundModesおよび background execution documentation をご覧ください。

Objc.ioの Multi-Tasking の記事も、このアプローチの良い出発点です。

バックグラウンドフェッチ

バックグラウンドモード Appleのドキュメントを読むと、アプリのUIBackgroudnModes値フェッチを使用して、日和見的に目覚めさせ、ダウンロードする時間を与えることができます。またはデータを更新します。

これに関するAppleのドキュメントには、ユースケースが記載されています。

新しいコンテンツを定期的にチェックする必要があるアプリは、システムにそれらのコンテンツを取得する操作を開始できるようにそれらを起動するように要求できます。このモードをサポートするには、Xcodeプロジェクトの[機能]タブの[バックグラウンドモード]セクションでバックグラウンドフェッチオプションを有効にします。

17
Jessedc

マルチタスクをオプトアウトできます。このように、アプリはバックグラウンドに入らないか、中断されません。アラートが表示される正しい時間を待ってください。ただし、これはおそらく電力使用量を考慮すると最適なソリューションではありません。また、アプリは常にアクティブである必要があります。ユーザーが[ホーム]ボタンを押すと、アプリは終了します。ただし、ユーザーがデバイスをロックしても、アプリは終了しません。これは、文書化されていないAPIを使用せずに実行できる最善の方法です。

アプリをバックグラウンドでまったく実行したくない場合は、UIApplicationExitsOnSuspendキー(値YES)をアプリのInfo.plistファイルに追加して、バックグラウンドから明示的にオプトアウトできます。アプリがオプトアウトすると、非実行状態、非アクティブ状態、およびアクティブ状態が繰り返され、バックグラウンドまたは一時停止状態にはなりません。ユーザーが[ホーム]ボタンを押してアプリを終了すると、アプリデリゲートのapplicationWillTerminate:メソッドが呼び出され、アプリは約5秒でクリーンアップして終了し、終了して非実行状態に戻ります。

バックグラウンドでの実行をオプトアウトすることは強くお勧めしませんが、特定の条件下では推奨されるオプションです。

https://developer.Apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

1
Tapani

あなたが求めているのはAppleのルールに反することであり、あなたのアプリが彼の許可なしにバックグラウンドで何かをこっそり実行することを誰も望まないでしょう。

そして、あなたが望んでいないすべてのオプションをリストしましたが、それらを頼りにしなければなりません。

それらをうまく組み合わせてユーザーフレンドリーにし、必要なものを近くで動作させる方法を考える必要があると思います。

これは私が考えることができる最高の組み合わせです:

  • 重大な場所の変更。最初に、場合によってはその後にユーザーの許可を求めます。
  • バックグラウンドフェッチ。呼び出されるたびにサーバーが何かを返すようにします。これにより、iOSが最適化して頻度を下げません。
  • サイレントプッシュ通知。最初にユーザーの許可を求めます。
1
dichen