0

In my app, I need to check the user's country, and then display an alert based on that. In the AppDelegate file, I have in didFinishLaunchingWithOptions:

self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    //Here you set the Distance Filter that you need
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    // Here you set the Accuracy
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    [self.locationManager startUpdatingLocation];

Then for the delegate I have this. It works, but the alert is constantly re-appearing. How do I only have it run this once?

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    NSLog(@"Running");
    CLLocation *newLocation = [locations lastObject];

    CLGeocoder *reverseGeocoder = [[CLGeocoder alloc] init];

    [reverseGeocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error)
     {


         CLPlacemark *myPlacemark = [placemarks objectAtIndex:0];
         NSString *countryCode = myPlacemark.ISOcountryCode;
         NSString *countryName = myPlacemark.country;
         NSLog(@"My country code: %@ and countryName: %@", countryCode, countryName);
         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
         if ([countryName isEqualToString:@"Thailand"]) {
             [defaults setBool:NO forKey:@"TestMode"];
             [defaults synchronize];
         }
         else {
             [defaults setBool:YES forKey:@"TestMode"];
             [defaults synchronize];
             UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Test Mode" message:@"Currently, live distribution is limited to the country of Thailand.  You may still use the app in 'Test Mode' to store distribution data on your machine.  When your country is added, you will have the option to upload it to our server." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
             [alert show];
         }

     }];




}
Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
user717452
  • 33
  • 14
  • 73
  • 149

2 Answers2

1

Instead of using...

[self.locationManager startUpdatingLocation];

...which tells the location manager to send updates about locations every time it gets a location update, why don't you use:

[self.locationManager requestLocation];

Which will only send you the first location the location manager gets.

Son of a Beach
  • 1,733
  • 1
  • 11
  • 29
  • What delegate method does that use, because it currently crashes the app. – user717452 Nov 08 '16 at 05:17
  • Refer to the documentation: https://developer.apple.com/reference/corelocation/cllocationmanager/1620548-requestlocation?language=objc (delegate method it uses is: locationManager:didUpdateLocations: ) – Son of a Beach Nov 08 '16 at 05:18
  • Where in your code did you put it? Can you post your updated code? Can you post the crash log? – Son of a Beach Nov 08 '16 at 05:20
  • It was because I hadn't put the didFailWithError delegate in. – user717452 Nov 08 '16 at 05:21
  • ah, I hadn't anticipated that... good to know... thanks for letting us know the extra requirement (I see now that it is in the docs, but didn't notice it when I looked earlier). – Son of a Beach Nov 08 '16 at 05:22
  • Spoke too soon...was working fine in simulator, but still displaying alert over and over again in actual device. – user717452 Nov 08 '16 at 05:29
  • Add an NSLog() to just before the alert shows and then run on the device, with debugging on the alert line. Then take a look at the stack trace on the SECOND (not first time) it is run, and tell us what it shows. – Son of a Beach Nov 08 '16 at 06:52
0

Take a bool value. It should be false for the first time. Then replace your code with this.

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    NSLog(@"Running");
    CLLocation *newLocation = [locations lastObject];
     [manager stopUpdatingLocation];

    CLGeocoder *reverseGeocoder = [[CLGeocoder alloc] init];
    [reverseGeocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error)
     {


         CLPlacemark *myPlacemark = [placemarks objectAtIndex:0];
         NSString *countryCode = myPlacemark.ISOcountryCode;
         NSString *countryName = myPlacemark.country;
         NSLog(@"My country code: %@ and countryName: %@", countryCode, countryName);
         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
         if ([countryName isEqualToString:@"Thailand"]) {
             [defaults setBool:NO forKey:@"TestMode"];
             [defaults synchronize];
         }
         else {
             [defaults setBool:YES forKey:@"TestMode"];
             [defaults synchronize];

              if(boolvar == false){
              boolvar = true

             UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Test Mode" message:@"Currently, live distribution is limited to the country of Thailand.  You may still use the app in 'Test Mode' to store distribution data on your machine.  When your country is added, you will have the option to upload it to our server." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
             [alert show];
         }
}
     }];

}
Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
User511
  • 1,456
  • 10
  • 28
  • I think something may be messed up on your boolvar = true line of code – user717452 Nov 08 '16 at 05:10
  • Before showing alert you just have to check if that bool variable is false then it will show alert. First time it will be false then you have set it to true it will never show alert again. – User511 Nov 08 '16 at 05:11
  • Right, I was just saying your code in this answer needs editing on its format, and it won't let me set the boolvar by simply stating `boolvar = true;` – user717452 Nov 08 '16 at 05:15