0

I am in the process of testing location updates via the background APIs that relaunch an app. I have successfully tested visits and regions and am using this same app to also test significantLocationChanges (SLC). I run my app, press home twice then swipe it off to kill it. Then I drive around. I can observe the app background activity without touching the phone via a server where (see code below) the singleton method sendBackgroundTestRecord uploads simple status messages to the server.

When I test visits and regions I have no problems. However when I test SLC, nothing happens until I turn the phone's screen on (pressing the power or home button once -- not re-running the app, or even unlocking the phone). I can drive a far distance without anything happening. I suspect the app has received an SLC event sometime during that drive because as soon as I turn the phone on for a about 2 seconds, the code below executes and I can observe the messages on the server.

I believe this is not just a network connectivity delay because the sendBackgrounTestRecord method uses a time stamp. The records on the server show a time stamp of when I turned the screen on, not when the SLC event is suspected to have fired.

I never have this problem with visits or regions, only SLC. By the way, the code has gone through many changes trying to chase this down. The latest attempt (code below) was to put everything in the appDelegate.

Any ideas? Thanks in advance for any ideas whatsoever!

EDIT: I added beginBackgroundTaskWithExpirationHandler, which was in my original tests too.

//  AppDelegate.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
  @property (strong, nonatomic) UIWindow *window;
  @property (strong, nonatomic) CLLocationManager *locationManager;
@end



//  AppDelegate.m

#import "AppDelegate.h"
#import "clsCommon.h"
@interface AppDelegate ()
@end
@implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Ask iOS for more time to process - before we do anything else
  [clsCommon sharedInstance].backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];

    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didFinishLaunchingWithOptions"];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
      [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    }
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    self.locationManager.allowsBackgroundLocationUpdates = YES;
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
      [self.locationManager requestAlwaysAuthorization];
    }

    [self.locationManager startMonitoringSignificantLocationChanges];

    return YES;
  }


  - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations"];
    CLLocation * currentLocation = [locations objectAtIndex:0];
    if(currentLocation !=nil) {
      [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations curLoc not nill"];
   }

 }

@end
John
  • 3
  • 6
  • Does it work as expected, that is delivering significant location change events without activating lock screen if you do not kill the app before starting to drive? – Alex Pavlov Apr 28 '16 at 18:30
  • I tried that too - leaving the app "running" and turning off the screen. Same problem. – John Apr 28 '16 at 18:48
  • Did you check "Location Updates" mode in Background Modes on. If background mode is npt turned on, then you will not get any updates – KrishnaCA Apr 28 '16 at 19:48
  • Yes, Location Updates is on as a background mode in Capabilities. And that is working for regions and visits, just not SLC. – John Apr 28 '16 at 19:50
  • Well, knowing how aggressively iOS resolves all tradeoffs in favor of battery life I would not be surprised very much. But let me try to reproduce the behavior first. Will test this on my drive back home today. Will share my findings. – Alex Pavlov Apr 28 '16 at 20:32
  • Great! Thanks Alex. Will be interesting if you get different results. iOS IS very aggressive in this area. However if this behavior is intended, it amounts to killing SLC altogether, since background relaunch is the intent of SLC per Apple documentation. Also, both regions and visits have similar intent and do work as documented. – John Apr 28 '16 at 20:46
  • It worked for me. Distances between SLC readings were in 4 to 14 km range, the smallest time gap between two consequent readings - 14 minutes. The app is very similar to yours, it does not include any networking part, just logging events to a local file (NSLog via stderr redirection). Also, I do not configure properties, which are irrelevant for SLC in location manager, like desiredAccuracy, distanceFIlter, activityType. I suggest you start from barebone app and watch for the improvement, which breaks it. – Alex Pavlov Apr 29 '16 at 12:59
  • I also loaded this on someone else's phone last night and it worked as well. So there is something particular to my phone. So I think your suggestion on a new app start and test with each block of code added is a good idea at this point. Thanks for your help Alex. – John Apr 29 '16 at 16:50
  • Alex, if you want to copy that into an answer, I can accept it as the solution. – John Apr 29 '16 at 17:16

2 Answers2

1

Well, knowing how aggressively iOS resolves all tradeoffs in favor of battery life I would not be surprised very much. For example, behavior of "breadcrumbs" app (set 100m geofence at your current location, move that geofence to new location on exit event) is very different depending on whether iPhone sleeps all the time in your pocket, or you check lock screen occasionally.

However, running an app very similar to yours while traveling back home yesterday did generate location updates for me.

Distances between SLC readings were in 4 to 14 km range, the smallest time gap between two consequent readings - 14 minutes. The app is very similar to yours, it does not include any networking part, just logging events to a local file (NSLog via stderr redirection). Also, I do not configure properties, which are irrelevant for SLC in location manager, like desiredAccuracy, distanceFIlter, activityType. I suggest you start from barebone app and watch for the improvement, which breaks it.

One thing to check is if your app crashes when handling location updates. If it happens in background you will not notice this unless you run logging or check crash logs via Settings.app.

mfaani
  • 33,269
  • 19
  • 164
  • 293
Alex Pavlov
  • 991
  • 6
  • 9
0

Put some distance in self.locationManager.distanceFilterand is better for battery change self.locationManager.pausesLocationUpdatesAutomatically=YES;

Start Location Manager in iOS 7 from background task

Community
  • 1
  • 1
Spidvmp
  • 263
  • 1
  • 6
  • 16
  • Thanks for your answer Spidvmp. My understanding of distanceFilter is that is has no effect on the GPS hardware, accuracy or frequency, but only filters out delivering some of the results to your code. It would seem counter-intuitive that reducing the frequency of GPS results would help in this case. And the same with further reducing the pass through with pausesLocationUpdates. However, those are just my thoughts. Is there something I'm missing there? I know sometimes things are not as they seem. – John Apr 29 '16 at 00:21
  • As per iOS reference: [significant location updates service] "does not rely on the value in the distanceFilter property to generate events". – Alex Pavlov Apr 29 '16 at 15:01
  • ...however, I did try your suggestions. But it did not fix the issue. – John Apr 29 '16 at 16:48