Getting user location when app is in background. I

2019-06-06 00:30发布

I'm developing an app that works in the background to get the user's location and send it to server using http requests. My first intention was to get the user's location every n minutes, but after alot of research and trial, i gave up since ios kills my background tasks after 3 minutes.

Then i tried working on MonitoringSignificantLocationChanges, but its inaccurate location updates due to cell tower usage ruins the purpose of my app.

A solution to any of the following is greatly appreciated:

  1. Getting user's location in background every n minutes infinitely.
  2. Getting user's location in background on SignificantLocationChanges with high accuracy(using gps)
  3. Any other background solution with high accuracy results.

2条回答
放荡不羁爱自由
2楼-- · 2019-06-06 00:56

Getting user's location in background on SignificantLocationChanges with high accuracy(using gps)

Do the following:

in info.plist add the following

    <key>NSLocationAlwaysUsageDescription</key>
    <string>{your app name} requests your location coordinates.</string>
    <key>UIBackgroundModes</key>
    <array>
        <string>location</string>
    </array>

in code use LoctionManager to get location updates, (it will work in both foreground and background)

@interface MyViewController <CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
@end 

@implementation MyViewController
-(void)startLocationUpdates {
    // Create the location manager if this object does not
    // already have one.
    if (self.locationManager == nil) {
        self.locationManager = [[CLLocationManager alloc] init];
    }

    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    self.locationManager.activityType = CLActivityTypeFitness;

    // Movement threshold for new events.
    self.locationManager.distanceFilter = 25; // meters

    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
    }
    [self.locationManager startUpdatingLocation];
}

- (void)stopLocationUpdates {
    [self.locationManager stopUpdatingLocation];
}

#pragma mark CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    // Add your logic here
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"%@", error);
}
查看更多
够拽才男人
3楼-- · 2019-06-06 01:12

This is what works for me, I use CLLocationManagerDelegate, register for updates on didUpdateLocations and in app Delegate

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [_locationManager stopMonitoringSignificantLocationChanges];
    [_locationManager startUpdatingLocation];
}

I start updating location, the key for me, is when the app goes to background I switch to Significant Location Changes so the app doesn't drain the batter like this:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [_locationManager startMonitoringSignificantLocationChanges];
}

In didUpdateLocations, you can check

BOOL isInBackground = NO;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
    isInBackground = YES;
}

And start a task in the background to report the location for example

if (isInBackground) {
    [self sendBackgroundLocationToServer:self.location];
}

And start a task, I hope that helps.

查看更多
登录 后发表回答