我的应用程序需要在后台跟踪用户的位置,但无法发送“get”请求。当应用程序回到前台时,http请求会立即发送。我使用RestKit处理所有网络请求,并遵循这个教程设置我的后台位置服务。在我的applicationDidEnterBackground方法中。
网络请求按计划进行,但不会在后台调用。我需要采取其他措施吗?在我的info.plist中,我有所需的后台模式键和位置服务作为值。
编辑
我还参考了这个SO答案。我在didUpdateToLocation调用中放置了一些日志测试,它们都被调用,但'get'请求没有被发送。相反,当我最终将应用程序启动到前台时,它发送了所有构建的网络请求(超过10个)。
编辑(2)
我向我的请求添加了RKRequestBackgroundPolicyContinue,但结果没有改变。(如您可以在此处看到的Restkit中的后台上传/下载)。我看到Restkit初始化主机,但直到应用程序变为活动状态才发送请求。
答案
RestKit必须正在执行某些在后台被禁止的操作。使用NSURLRequest完美地工作。
-(void)applicationDidEnterBackground:(UIApplication *)application
{
self.bgLocationManager = [[CLLocationManager alloc] init];
self.bgLocationManager.delegate = self;
[self.bgLocationManager startMonitoringSignificantLocationChanges];
NSLog(@"Entered Background");
}
我在applicationDidBecomeActive委托中停止监控显著位置变化。
这是我的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答案。我在didUpdateToLocation调用中放置了一些日志测试,它们都被调用,但'get'请求没有被发送。相反,当我最终将应用程序启动到前台时,它发送了所有构建的网络请求(超过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会被后台任务打扰,因此使用同步请求是可以的。
[[RKClient sharedClient] post:params:delegate:]
很可能会导致一些在后台GCD队列中发生的事情,这些事情可能不被你的backgroundTask括号所覆盖...而同步调用以获取数据可能有助于在后台任务中发送请求。是的,RKRequestBackgroundPolicyContinue可能旨在解决此问题,但实际上直到调用post:params:delegate:之后才设置它,那时可能已经太晚了。 - john.k.doe