What is best iOS GPS (CLLocationManager) battery saving technique

210 views Asked by At

Ive written a GPS app for iOS 10 a while back. Ive gotten it to the point where its stable and working as expected and now I want to go after battery saving techniques. The app sends GPS locations every 5 minutes right now but I could be flexible on how often I send the GPS locations, as long as they aren't sent too infrequently. My app requires 'best' or '10m' GPS location setting as well which I know uses a lot of power, but I cannot use the 3km setting per my requirements (which I know would save more power).

From what I gather and reading the docs and playing with code to make it work, it seems that there are 2 techniques:

  1. set pausesLocationUpdatesAutomatically = YES in combination with UNLocationNotificationTrigger
  2. allowDeferredLocationUpdatesUntilTraveled:timeout:

Number 2 apparently does not work at all based on this article in iOS 10 and 11.

Number 1 gives me sporadic results when I log it to my server. Sometimes it works, sometimes Ill get a single GPS point in the middle of nowhere (without seeing a pause or resume log message) and then later it starts to work, other times it does not seem to work at all.

Sometimes Ill see 2 pauses back to back within the same second.

Other times Ive seen it resume locations back to back (minutes apart) without ever seeing the pause log message. And other times I see the pause log message and minutes later (or a while later) resume GPS sends without seeing a 'resume' log message.

- (void) setGPSBatterySavingTrigger
{
    if (IS_IOS_10_OR_LATER && ([g_prefs getGPSAuthStatus] == kCLAuthorizationStatusAuthorizedAlways))
    {
        CLLocationCoordinate2D center = CLLocationCoordinate2DMake(g_locMgr.getLastLocation.latitude, g_locMgr.getLastLocation.longitude);
        CLRegion *region = nil;
        float radius_m = 150.0;
        region = [[CLCircularRegion alloc] initWithCenter:center radius:radius_m identifier:@"pauseLocationsCenter"];

        if (!region) {
            [logger log:TSERVLOG :@"pause radius failed at radius <%f>", radius_m];
            return;
        }
        region.notifyOnEntry = NO;
        region.notifyOnExit = YES;

        UNLocationNotificationTrigger *trigger = [UNLocationNotificationTrigger
                                                  triggerWithRegion:region repeats:NO];

        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        content.title = PROG_NAME;
        content.body = @"GPS Restarted";
        //content.sound = [UNNotificationSound soundNamed:nil];

        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"GPSTextNotify" content:content trigger:trigger];

        [[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *error)
         {
             if (error.code)
             {
                 [logger log:TSERVLOG :@"UNUserNotificationCenter addRequest FAILED <%@>", error.localizedDescription];
             }
         }];
    }
}

- (void) locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager
{
    [logger log:TSERVLOG :@"===== JME GPS PauseLocationUpdates at <%@> <%f, %f>",
            [mydate getCurrentDateTimeStr], self.getLastLocation.latitude, self.getLastLocation.longitude];

    [self setGPSBatterySavingTrigger];
}

- (void) locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager
{
    [logger log:TSERVLOG :@"===== GPS ResumeLocationUpdates at <%@> <%f, %f>",
            [mydate getCurrentDateTimeStr], self.getLastLocation.latitude, self.getLastLocation.longitude];
}

Bottom line questions:

  1. Has anyone been able to use either of these to get battery saving + GPS working reliably in iOS 10+?
  2. If not, what combination of things did you do to get it to work 100% of the time while saving battery life?
  3. Am I missing another technique that does work? (NOTE my requirements cannot use the 3km setting)

Thank you for your input!

0

There are 0 answers