0

I've read so many question here at stackoverflow and I am still having issues with CLLocationManager.I have already added keys in info.plist (NSLocationAlwaysAndWhenInUseUsageDescription,NSLocationWhenInUseUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription). My app supports ios 9.0 to 11.x.

Update:- I'm testing on iphone6 ios 11.0.3 physical device

My Approach - 1. Start updating location after while using the app permission. 2. When app goes into background stop location manager to remove Blue Banner (Banner Of Shame) 3.Fire a periodic timer of 30 seconds and start location manager again. This time I never got the delegate callback didUpdateLocation

I have a singleton class called LocationManager. Here is my code from LocationManager and AppDelegate

LocationManager

- (void)startLocatingUser {
    //Locate User
    _locationMeasurements = [NSMutableArray array];
    self.geocoder = [[CLGeocoder alloc] init];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;


    if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
        [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    }

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


        if (@available(iOS 11.0, *)) {
            self.locationManager.showsBackgroundLocationIndicator = NO;
        } 

    [self.locationManager startUpdatingLocation];

}

- (void)stopLocatingUser {

    if(self.locationManager) {
        [self.locationManager stopUpdatingLocation];
    }
}

AppDelegateCode

- (void)applicationWillResignActive:(UIApplication *)application {

    _isBackgroundMode = YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    LocationManager* locationManager = [LocationManager sharedLocationManager];
    [locationManager stopLocatingUser];



    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    self.bgTimer = [NSTimer scheduledTimerWithTimeInterval:30.0
                                                      target:self
                                                    selector:@selector(startTrackingBg)
                                                    userInfo:nil
                                                     repeats:YES];
}

-(void)startTrackingBg {
    dispatch_async(dispatch_get_main_queue(), ^{
        LocationManager* locationManager = [LocationManager sharedLocationManager];

        [locationManager startLocatingUser];
    });

    NSLog(@"App is running in background");
}

I am never getting this delegate callback in background once I stop and start location manager again.

- (void)locationManager:(CLLocationManager *)manager

     didUpdateLocations:(NSArray *)locations

What I simply want is whenever user puts the app in background. I want to hide the banner of shame and then I need periodic location updates in background and send them to server.

Rahul Vyas
  • 28,260
  • 49
  • 182
  • 256

0 Answers0