如何永远在后台运行iOS Core Location

我正在为我们的办公室创建自定义应用程序。 我希望这个应用程序每5分钟(或左右)获取用户的位置,并通过json将其发送到我们的服务器。 我有它工作,但它不会在后台运行超过10分钟(我可以告诉)。

我在所需的后台模式中添加了“应用寄存器以进行位置更新”。

我的代码在AppDelegate中,如下所示:

- (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"Became active"); // Start location services locationManager = [[CLLocationManager alloc] init]; locationManager.desiredAccuracy = kCLLocationAccuracyBest; locationManager.distanceFilter = 100.0f; locationManager.delegate = self; [locationManager stopMonitoringSignificantLocationChanges]; [locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { BOOL isInBackground = NO; if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { isInBackground = YES; } NSLog(@"Location Manager isInBackground: %hhd", isInBackground); if (isInBackground) { [self sendBackgroundLocationToServer:newLocation]; } else { [self sendDataToServer:newLocation]; } } -(void) sendBackgroundLocationToServer:(CLLocation *)location { bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [[UIApplication sharedApplication] endBackgroundTask:bgTask]; }]; // Send the data [self sendDataToServer:location]; if (bgTask != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; } } -(void) sendDataToServer:(CLLocation *)newLocation { NSLog(@"Sending Data to Server"); // Get battery level [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; float batteryLevel = [[UIDevice currentDevice] batteryLevel]; float lat = newLocation.coordinate.latitude; float lng = newLocation.coordinate.longitude; NSLog(@"Accuracy: %f", newLocation.horizontalAccuracy); NSString *userId = [[NSUserDefaults standardUserDefaults] stringForKey:@"userId"]; NSString *post = [[NSString alloc] initWithFormat:@"login_id=%@&latitude=%f&longitude=%f&speed=%f&course=%f&battery_level=%f&horizontal_accuracy=%f&vertical_accuracy=%f", userId, lat, lng, [newLocation speed], [newLocation course], batteryLevel, newLocation.horizontalAccuracy, newLocation.verticalAccuracy]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; NSString *urlstring = [NSString stringWithFormat:@"%@webservice/post_logins_location.php", kBaseURL]; [request setURL:[NSURL URLWithString:urlstring]]; [request setHTTPMethod:@"POST"]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; NSError *error; NSURLResponse *response; NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; jsonResults = [NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error]; NSLog(@"GPS Send results: %@", jsonResults); _lastSentUpdateAt = [NSDate date]; } 

我也尝试使用startMonitoringSignificantLocationChanges并完全删除_lastSentUpdateAt。 但是我仍然得到相同的结果。 我现在的问题是,json可以在10分钟后从后台发送数据吗? 现在我的手机已经运行了一个多小时,我的应用程序的位置服务图标仍处于活动状态。 但是,我没有看到任何数据在我的服务器上发布更新。 一旦我实际打开我的应用程序,它确实收到更新,这使我相信在后台发送数据时出现问题。 或者还有其他事情发生了吗?

阅读文档并观看与“注册重要位置更新”相关的WWDC演示文稿。 他们已经改进并改变了官方建议的做法,同时谨慎使用功耗。

具体而言,无法以指定的时间间隔获取背景位置。 重要的位置更新由操作系统自行决定,并受到应用程序无法控制的许多因素的影响。

如果您要做的就是让应用程序不在后台终止,您需要在应用程序的plist中声明这种背景模式。 它位于Xcode的“Info”下,我认为是“应用寄存器进行位置更新”。