如何永远在后台运行iOS Core Location [英] How to run iOS Core Location in background forever

查看:89
本文介绍了如何永远在后台运行iOS Core Location的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a custom application for our office. I want this app to get the user's location every 5 minutes (or so) and send it to our server via json. I have it working however it won't run in the background longer than 10 minutes (that I can tell).

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

I have added "App registers for location updates" in Required background modes.

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

My code is in the AppDelegate, like this:

- (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分钟后从后台发送数据吗?现在我的手机已经运行了一个多小时,我的应用程序的位置服务图标仍处于活动状态。但是,我没有看到任何数据在我的服务器上发布更新。一旦我实际打开我的应用程序,它确实收到更新,这使我相信在后台发送数据时出现问题。或者还有其他事情发生吗?

I have also tried it with startMonitoringSignificantLocationChanges and removing the _lastSentUpdateAt completely. However I'm still getting the same results. My question now is, can json send data from the background after 10 minutes? Right now my phone has been running for over an hour and the Location Services icon is still active for my app. However I'm not seeing any data hit my server with updates. Once I actually opened my app, it did receive updates which makes me believe that there is an issue sending the data in the background. Or is there something else going on?

推荐答案

阅读文档并观看与注册重要位置更新相关的WWDC演示文稿。 他们对官方推荐的方法进行了改进和修改,同时对功耗进行了谨慎处理。

Read the documentation and watch the WWDC presentations related to "registering for significant location updates." They have made improvements and changes to the officially recommended ways of doing this while being prudent with power consumption.

具体来说,一次无法获得后台位置你指定的间隔。重要的位置更新由操作系统自行决定,并且受到应用程序无法控制的许多因素的影响。

Specifically, there is no way to get the background location at a time interval you specify. Significant location updates fire at the discretion of the OS, and are influenced by many factors beyond your app's control.

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

If all you're trying to do is keep the app from being terminated in the background, you'll need to declare that kind of background mode in the plist for your app. It's under "Info" in Xcode, under "App registers for location updates" I think.

这篇关于如何永远在后台运行iOS Core Location的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆