我的应用程序需要在后台跟踪用户位置,但它未能发送“获取”请求。当应用程序进入前台时,http 请求会立即发送。我正在使用 RestKit 处理我的所有网络请求,并按照本教程设置我的后台位置服务。在我的 applicationDidEnterBackground
-(void)applicationDidEnterBackground:(UIApplication *)application
{
self.bgLocationManager = [[CLLocationManager alloc] init];
self.bgLocationManager.delegate = self;
[self.bgLocationManager startMonitoringSignificantLocationChanges];
NSLog(@"Entered Background");
}
我在我的 applicationDidBecomeActive 委托中停止MonitoringSignificantLocationChange
这是我的 locationManager 委托,我接受新的更新位置并将其发送到我的服务器
-(void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(@"I am in the background");
bgTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:
^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
// ANY CODE WE PUT HERE IS OUR BACKGROUND TASK
NSString *currentLatitude = [[NSString alloc]
initWithFormat:@"%g",
newLocation.coordinate.latitude];
NSString *currentLongitude = [[NSString alloc]
initWithFormat:@"%g",
newLocation.coordinate.longitude];
NSString *webToken = [[NSUserDefaults standardUserDefaults] stringForKey:@"userWebToken"];
NSLog(@"I am in the bgTask, my lat %@", currentLatitude);
NSDictionary *queryParams;
queryParams = [NSDictionary dictionaryWithObjectsAndKeys:webToken, @"auth_token", currentLongitude, @"lng", currentLatitude, @"lat", nil];
RKRequest* request = [[RKClient sharedClient] post:@"/api/locations/background_update" params:queryParams delegate:self];
//default is RKRequestBackgroundPolicyNone
request.backgroundPolicy = RKRequestBackgroundPolicyContinue;
// AFTER ALL THE UPDATES, close the task
if (bgTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
网络请求按计划工作,但不会在后台调用。我还需要什么额外的步骤吗?在我的 info.plist 中,我将所需的背景模式键和位置服务作为值。
编辑
我还提到了这个过去的 SO answer。我在整个 didUpdateToLocation 调用中运行了一些测试,它们都被调用了,但没有发送“获取”请求。相反,当我最终将应用程序启动到前台时,它发送了所有构建的网络请求(超过 10 个)。
编辑 (2) 我将 RKRequestBackgroundPolicyContinue 添加到我的请求中,但它并没有改变我的结果。(正如您在restkit的后台上传/下载中看到的那样)。我看到 Restkit 初始化主机,但在应用程序激活之前无法发送请求。
回答
RestKit 必须在后台做一些被禁止的事情。使用 NSURLRequest 效果很好。
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com/api/locations/background_update"]];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:jsonData];
NSHTTPURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
使用同步请求很好,因为没有 UI 可以中断后台任务