significant location change does not trigger on device

无人久伴 提交于 2019-11-29 04:26:25

There are several problems with the code:

  1. The location updates are not started when the app is launched by iOS.
  2. Background location updates are not requested.
  3. The code relies on changes in authorization status to start location updates
  4. There is a missing break statement in the didChangeAuthorizationStatus method.

Here are the relevant documents:

The first document says a location manager object must be fully configured when iOS launches the app so the location event can be delivered to the app.

Upon relaunch, you must still configure a location manager object and call this method [startMonitoringSignificantLocationChanges] to continue receiving location events.

This is how I usually do it to ensure that the location manager is fully started regardless of if it was launched from the icon or by iOS (sorry I use ObjectiveC).

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

  NSLog(@"app launching");
  bgTask = UIBackgroundTaskInvalid;

  locationMgr = [[CLLocationManager alloc] init];
  [locationMgr setDelegate:self];
  if([locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
    [locationMgr setAllowsBackgroundLocationUpdates:YES];
  CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];

  if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
    NSLog(@"relaunching because of significant location change - restarting SLC");
    [locationMgr startMonitoringSignificantLocationChanges];
  }
  else
  {
    if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
        NSLog(@"launching with authorization to always use location - starting SLC");
        [locationMgr startMonitoringSignificantLocationChanges];
    }
    else
    {
        NSLog(@"launching with no authorization to always use location - requesting authorization");
        if([locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)])
            [locationMgr requestAlwaysAuthorization];
    }
  }

  return YES;
}

Notice the call to setAllowsBackgroundLocationUpdates. This is new in iOS9 and must be done everytime the app starts if you want to receive locations updates in the background. (It is like a "I'm not kidding, I know I asked for them in the background modes, but I really do want them").

Apps that want to receive location updates when suspended must include the UIBackgroundModes key (with the location value) in their app’s Info.plist file and set the value of this property to YES.

Finally you can't rely on didChangeAuthorizationStatus being called. If you have the authorization kCLAuthorizationStatusAuthorizedAlways then calling [locationMgr requestAlwaysAuthorization] doesn't result in a change in authorization status, so didChangeAuthorizationStatus isn't called.

If the authorization status is already known when you call the requestWhenInUseAuthorization or requestAlwaysAuthorization method, the location manager does not report the current authorization status to this method.

I think you have to startUpdatingLocation regardless? Have you tried inserting breakpoints to see where you get to?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!