【问题标题】:iOS background Region Location updatesiOS后台Region Location更新
【发布时间】:2012-12-11 23:01:22
【问题描述】:

我正在构建一个带有区域监控的应用程序。它在前台工作正常,但是一旦应用程序在后台发送,它的行为就不像预期的那样:它确实调用了 didEnter 和 didExit 但一旦它开始执行回调它就会停止。在这些回调方法中,我需要轮询服务器并保持 didExitRegion 和/或 didEnterRegion 状态。一旦我再次将应用程序置于前台,任何排队的请求都会启动并完成。 任何想法? 我在 iphone 4 上使用 ios5.1 和 ios6

【问题讨论】:

    标签: ios background location monitoring region


    【解决方案1】:

    当你在后台被调用时

    - (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

    【讨论】:

      【解决方案2】:

      如果你想活下去,你必须请求额外的时间。 请参阅有关后台模式的 applle 文档。有一种方法。 通常,您不会“被允许”在任何任务的后台保持活动状态。仅适用于特定的,例如 GPS。 尝试在每次区域更新后请求额外的后台时间。

      【讨论】:

      • 我想我在某处读到最多大约 10 分钟...我需要后台连续区域位置更新
      • 您的区域更新是连续的,但您的进一步任务不是,除了收到区域更新请求的时间。
      【解决方案3】:

      如果您尚未将“位置”添加到 Info.plist 的 UIBackgroundModes。作为第二个想法,我会使用AFNetworking,它广受欢迎并且具有后台支持。这意味着它将处理设置参数以告诉操作系统它会“在我回去睡觉之前完成这件事”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-03
        • 2014-07-24
        • 1970-01-01
        相关资源
        最近更新 更多