0

リージョン監視を使用してアプリを構築しています。フォアグラウンドでは正常に動作しますが、アプリがバックグラウンドで送信されると、期待どおりに動作しません。didEnter と didExit を呼び出しますが、コールバックの実行を開始するとすぐに停止します。これらのコールバック メソッドでは、サーバーをポーリングし、didExitRegion および/または didEnterRegion ステータスを保持する必要があります。アプリを再びフォアグラウンドにするとすぐに、キューに入れられたすべてのリクエストが開始され、完了します。何か案が?iphone 4でios5.1とios6を使っています

4

3 に答える 3

2

バックグラウンドで呼び出されたとき

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region

(または...終了)

サーバー呼び出しに必要なもの(変数、サーバーのペイロードなど)をセットアップするだけです。実際の送信開始前に

self.bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [[UIApplication sharedApplication] endBackgroundTask:self.bgTaskId];
    self.bgTaskId = UIBackgroundTaskInvalid;
    somelogger(@"ran out of time for background task");

    // remember that we failed for the next time the app comes to the foreground
}];

次に、選択した HTTP フレームワークで実際の送信を行い、完了ハンドラーでバックグラウンド タスクを次のようにリセットします。

[[UIApplication sharedApplication] endBackgroundTask:self.bgTaskId];

AFNetworking を使用した例:

[self.httpClient postPath:@"state" parameters:@{@"abc": abc, @"value": val, @"h": h, @"app":myAppName , @"version": myAppVersion }
    success:^(AFHTTPRequestOperation *operation, id responseObject) {
      if (operation.response.statusCode != 200) {
          DDLogVerbose(@"response was not 200. error: %i", operation.response.statusCode);

      } else {
          DDLogVerbose(@"success");

      }

      [[UIApplication sharedApplication] endBackgroundTask:self.bgTaskId];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      DDLogVerbose(@"request error %@, current retry count %d", error, retryCount );

      // start our own retry mechanism
      if (retryCount < MAX_RETRIES) {
          retryCount++;
          double delayInSeconds = RETRY_INTERVAL * (1 + (double)retryCount/10);
          dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
          dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
              // try again
          });
      } else {
          // final
          [[UIApplication sharedApplication] endBackgroundTask:self.bgTaskId];

          // remember failure when app comes back to foreground
      }

    }];

私は使用しています

@property (assign, nonatomic) UIBackgroundTaskIdentifier bgTaskId;

バックグラウンド識別子を保存します。

全体のメカニズムはhttp://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW28で説明されています

于 2012-12-18T18:00:33.377 に答える
0

生き続けたい場合は、追加の時間をリクエストする必要があります。バックグラウンドモードについてはアップルのドキュメントを参照してください。そのための方法があります。一般に、どのタスクでもバックグラウンドでアクティブなままでいることは「許可」されていません。GPS などの特定のもののみ。各地域の更新後に追加のバックグラウンド時間をリクエストしてみてください。

于 2012-12-11T23:06:29.053 に答える
-1

Info.plistのUIBackgroundModesに「location」をまだ追加していない場合。2番目のアイデアとして、広く普及していてバックグラウンドをサポートしているAFNetworkingを使用します。つまり、「スリープ状態に戻る前にこれを終了する」ことをOSに通知するためのパラメーターの設定を処理します。

ここに画像の説明を入力してください

于 2012-12-11T23:21:11.503 に答える