0

AppDelegate.m this is for detecting the app when it returns from background, so the monitoring of the significant location changes gets restarted...as should be done

if([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"] != nil) {
    _restartloc = [[NSNumber alloc] initWithInt:1];
}
else {
    _restartloc = [[NSNumber alloc] initWithInt:0];
}

ViewController.h the locationManager is a (strong, nonatomic) property, it is supposed to be strong, I am not sure about the nonatomic in this scenario

...

@interface ViewController : UIViewController <GMSMapViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CLLocationManagerDelegate>

@property (nonatomic) UIImagePickerController *imagePickerController;

#if TARGET_OS_IPHONE
@property NSMutableDictionary *completionHandlerDictionary;
@property (strong, nonatomic) AFHTTPSessionManager *manager;
@property (strong, nonatomic) CLLocationManager *locationManager;

...

ViewController.m in the viewDidLoad method, I check if the app is coming from background, and restart the locationManager if needed. The startSignificantChangeUpdates method never seems to get called, I put in alerts so that I could test as I was walking around. I never see anything from didUpdateLocations (or any other CLLocationMangerDelegate method).

- (void)viewDidLoad {

    ...

    if(((AppDelegate *)[UIApplication sharedApplication].delegate).restartloc == [[NSNumber alloc] initWithInt:1]) {
        [_locationManager stopMonitoringSignificantLocationChanges];

        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;

        [_locationManager startMonitoringSignificantLocationChanges];
    }

    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;

    if([_locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
        [_locationManager setAllowsBackgroundLocationUpdates:YES];
    }

    ...
}


- (void)startSignificantChangeUpdates
{
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
    // Create the location manager if this object does not
    // already have one.
    if (nil == _locationManager) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
    }

    //if ([CLLocationManager locationServicesEnabled]){

        //NSLog(@"Location Services Enabled");

    if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
        [_locationManager requestAlwaysAuthorization];
    }
    else if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusRestricted || [CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied) {
        deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"AUTH" message:@"Not allowed by phone to proceed with location services priveleges" preferredStyle:UIAlertControllerStyleAlert];

        [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
    }
    else if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedWhenInUse) {
        [_locationManager requestAlwaysAuthorization];
    }
    else {
        //
    }

    [CLLocationManager significantLocationChangeMonitoringAvailable];
    [_locationManager startMonitoringSignificantLocationChanges];
}

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"didFailWithError: %@", error);
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
}

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)_locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations {
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
    // If it's a relatively recent event, turn off updates to save power.
    CLLocation* location = [locations lastObject];
    NSDate* eventDate = location.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (fabs(howRecent) < 0.5) {
        // If the event is recent, do something with it.
        NSLog(@"latitude %+.6f, longitude %+.6f\n",
              location.coordinate.latitude,
              location.coordinate.longitude);
    }
}

From what I can see, it seems like a problem with the delegate, the methods never get called. Am I setting this up wrong? It's my first time using significant location changes.

UPDATE

This is my setup now, I am still not receiving any of the alerts from the delegate functions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];

    _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];
        }
    }

    if([userdefaults objectForKey:@"pfuser"] == nil) {
        NSLog(@"in delegate signup");
        SignUpController *signup = [[SignUpController alloc] init];
        [self.window setRootViewController:signup];
    }
    else {
        ViewController *map = [[ViewController alloc] init];
        [self.window setRootViewController:map];
    }
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)startSignificantChangeUpdates
{
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
    // Create the location manager if this object does not
    // already have one.
    if (nil == _locationMgr) {
        _locationMgr = [[CLLocationManager alloc] init];
        _locationMgr.delegate = self;
    }

    [CLLocationManager significantLocationChangeMonitoringAvailable];
    [_locationMgr startMonitoringSignificantLocationChanges];
}

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"didFailWithError: %@", error);
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
}

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)_locationManager:(CLLocationManager *)manager
      didUpdateLocations:(NSArray *)locations {
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert];

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert];
    // If it's a relatively recent event, turn off updates to save power.
    CLLocation* location = [locations lastObject];
    NSDate* eventDate = location.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (fabs(howRecent) < 15.0) {
        // If the event is recent, do something with it.
        NSLog(@"latitude %+.6f, longitude %+.6f\n",
              location.coordinate.latitude,
              location.coordinate.longitude);
    }
}
ewizard
  • 2,801
  • 4
  • 52
  • 110
  • Why is `restartLoc` an NSNumber instead of a simple bool? You should put your location manager on AppDelegate or its own class rather than in a view controller. Why do you call `significantLocationChangeMonitoringAvailable` but not do anything with the result? – Paulw11 Sep 17 '16 at 00:13
  • the result is `didUpdateLocations` right? I have an alert in there and it never happens. Is that where they are received? I'll put the locationmanager in the appdelegate....does it ever need to be referenced in a view controller? – ewizard Sep 17 '16 at 00:19
  • No, that method returns a bool that indicates whether significant location monitoring is available. Once you turn significant location monitoring on it will deliver updates to your delegate method. Do you get prompted to allow location access the first time you run your app? – Paulw11 Sep 17 '16 at 00:25
  • oh ok...i changed it to be how you said...with help from this example http://stackoverflow.com/questions/35467603/significant-location-change-does-not-trigger-on-device - im going to test it tomorrow. – ewizard Sep 17 '16 at 00:55
  • @Paulw11 i updated it to how i have it now...still the same problem...i moved everything out of the view controller and into the delegate – ewizard Sep 17 '16 at 16:51
  • http://stackoverflow.com/questions/39549400/significant-change-location-delegate-methods-not-being-called – ewizard Sep 17 '16 at 17:00

0 Answers0