3

概要

会社から、デバイスの位置を 2 時間ごとに確認できるアプリケーションのリリースを求められています。アプリは、TCP/IP ソケットを介してこれらの位置データをサーバーに送信し、これらのデータに応じて (同じ TCP/IP ソケットを介して) すぐに情報を受信します。したがって、アプリケーションを継続的にバックグラウンド モードで実行しようとしているわけではありません(実際、これは iOS で話題になっているようで、私のプロジェクトにも適していません)。

質問

信頼できるものにするために、これを達成するためのベストプラクティスは何ですか? だから、私は知りたいです:

  • 私のアプリは中断されている (= 非アクティブ) ため、Apple はソケットを開いて位置情報を送信することを許可していますdidUpdateToLocationか?
  • ソケットを介して送信/受信タスクを実行する必要がある時間はどれくらいですか?
  • 実際のバックグラウンド タスクを作成し、beginBackgroundTaskWithExpirationHandlerCocoa で許可されている 10 分間を使用して送信/受信タスクを実行する必要がありますか?
  • 2 時間ごとに 10 分間のバックグラウンド タスクを人間の操作なしで (つまり、ユーザーがアプリを再度開く必要があるなど) 要求することは可能です (Apple によって許可されています)。

これまでに達成/発見したこと

  • アプリが非アクティブなときにハンドラーを実行できるように、locationキーを追加しました。Info.plistdidUpdateToLocation
  • アプリケーションがフォアグラウンド (= アクティブ) のときに開いたソケットを介してデータを送受信できます。
  • backgroundTimeRemainingいつdidUpdateToLocation呼び出されるかを調べてみました。非常に大きな結果数が得られましたが、これは正常なようです。なぜなら、この時点でapplicationStateは ではなく にUIApplicationStateBackgroundあるからUIApplicationStateActiveです。

これらの点は公式文書ではあまり明確ではなく、私の特定のケースに関連するトピックは見つかりませんでした。

ご協力いただきありがとうございます。

4

1 に答える 1

5

Apple のドキュメントによると、説明したものと非常によく似たアプローチを使用してこれらを実現できます。私がすることは、この投稿で mindsizzlers によって説明されていることと似たようなことです:

  • 推奨事項として、アプリがバックグラウンドに入ったときに重要な位置情報の更新をオンにして、バッテリーを節約します。アプリがバックグラウンドになったときにこれを行うことができます。

    - (void) applicationDidEnterBackground:(UIApplication *) application
    {
        // Create the location manager if you do not already have one.
        if (nil == locationManager)
            locationManager = [[CLLocationManager alloc] init];
    
        locationManager.delegate = self;
        [locationManager startMonitoringSignificantLocationChanges];
    }
    

    次に、ドキュメントで説明されているように、場所が変更されるとシステムがアプリを起動します。

    このサービスを実行したままにし、その後アプリを一時停止または終了した場合、新しい位置データが到着すると、サービスによってアプリが自動的に起動されます。ウェイクアップ時に、アプリはバックグラウンドに入り、位置データを処理するための短い時間が与えられます。アプリはバックグラウンドにあるため、最小限の作業を実行し、割り当てられた時間が経過する前に戻るのを妨げる可能性のあるタスク (ネットワークへのクエリなど) を回避する必要があります。そうでない場合、アプリが終了する可能性があります。

    新しい場所をサーバーに送信するアクションの信頼性が非常に低くなるのを避けるために (場合によっては機能する場合があります)、完了まで実行できるバックグラウンド タスクを実行していることを iOS に事前に通知する必要があります。

  • ロケーション マネージャー デリゲート (didUpdateToLocation) を変更して、バックグラウンドでのロケーション更新を処理します。

    - (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
    {
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
            // Send the new location to your server in a background task
            // bgTask is defined as an instance variable of type UIBackgroundTaskIdentifier
            bgTask = [[UIApplication sharedApplication] 
            beginBackgroundTaskWithExpirationHandler:
            ^{
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
            }];
    
            // Make a SYNCHRONOUS call to send the new location to our server
    
            // Close the task
            if (bgTask != UIBackgroundTaskInvalid) {
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
                bgTask = UIBackgroundTaskInvalid;
            }
    
        } else {
                // Handle location updates in the normal way
        }   
    }
    

これにより、タイマーを実行する必要がなくなります。自動的にウェイクアップされ、更新された場所が大幅に変更されるたびにサーバーに送信されるため.

もちろん、これが特定の間隔で確実に行われるようにしたい場合は、タイマーを設定して位置情報の更新の受信を開始し、それを取得したらすぐにサーバーに送信する方法を使用できます. iOS のバックグラウンド モード(セクション:位置情報更新の受信)について説明しているこの投稿と、これを行う方法の詳細については、この他の質問を参照してください。

于 2013-07-31T13:31:30.313 に答える