I am writing a code to constantly track the user applying CoreLocation
. Since I cannot keep the GPS on all the time, I use StartMonitoringSignificantLocationChange
in my AppDelegate
to detect a significant change. I have registered for location
in the UIBackgroundMode
.
in didUpdateLocations
method, I check the current distance from the previously recorded location. If it is significant, I apply StopMonitoringSignificantLocationChange
and StartUpdatingLocation
to get accurate locations. Meanwhile I initiate a timer (30 secs) to see whether the user is stationary or moving. If the user is not moving anymore, I apply StopUpdatingLocation
and StartMonitoringSignificantLocationChange
again.
I have also defined a background task in my AppDelegate: -(void)applicationWillResignActive:(UIApplication *)application
as follows:
- (void)applicationWillResignActive:(UIApplication *)application
{
if (![[GeoSampleManager sharedManager] isLiveTracking])
{
GeoSampleManager *manager = [HTSGeoSampleManager sharedManager];
[manager.locationManager stopMonitoringSignificantLocationChanges];
self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
[manager.locationManager startMonitoringSignificantLocationChanges];
}
}
I close the background task when the app eneters foreground:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(self.bgTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}
}
And here is my didUpdateLocations
method:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation* newLocation = [locations lastObject];
if(self.isLiveTracking)
{
//Test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0 || newLocation.horizontalAccuracy > 200)
{
return;
}
if([self.lastLocation distanceFromLocation:newLocation] > 0)
{
//Create and save a GeoSample
[GeoSampleManager createSampleForLocation:newLocation onTrip:self.activeTrip];
self.lastLocation = newLocation;
}
}
else
{
if([self.lastLocation distanceFromLocation:newLocation] > 0)
{
[self.locationManager stopMonitoringSignificantLocationChanges];
self.idleChecker = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(checkIdle:) userInfo:nil repeats:YES];
[self.locationManager startUpdatingLocation];
self.isLiveTracking = YES;
}
}
}
And finally here is the timer method:
- (void)checkIdle:(NSTimer*)timer
{
if(abs([self.lastLocation.timestamp timeIntervalSinceNow]) >= 30.0)
{
//Stopping the idle-time checking timer
[self.idleChecker invalidate];
self.idleChecker = nil;
[self.locationManager stopUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
self.isLiveTracking = NO;
}
}
However, the app is suspended (sometimes after 5-10 secs, sometimes after 10 mins) and stops receiving location updates.Since I am struggling with this problem for more than a month and I have tried almost all possible solution, I really appreciate if you can help me to solve the issue in any way.
Cheers