title: iOS Geofence, how to handle when inside region when monitoring starts?
body: <p>I have been unable to work out how to handle a scenario where the phone is already inside a region when <code>startMonitoringForRegion</code> is called? Other questions have suggested calling <code>requestStateForRegion</code> inside <code>didStartMonitoringForRegion</code> this then calls the method <code>didDetermineState: forRegion:</code>. So the code looks something like this:</p>
  
  <pre><code>- (void)viewDidLoad {
      //location manager set up etc...
      for (Object *object in allObjects){
  
          CLRegion *region = [self geofenceRegion:object];
          [locationManager startMonitoringForRegion:region];
       }
  }
  
  - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
  
      [self.locationManager requestStateForRegion:region];
      [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5];
   }
  
  - (void)locationManager:(CLLocationManager *)manager
    didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
  
      if (state == CLRegionStateInside){
          [self locationManager:locationManager didEnterRegion:region];
      }  
  }
  </code></pre>
  
  <p>Now obviously the method geofenceRegion is my own and it works fine, and the objects contains things like lat long and radius and that all works fine as well so that is not the problem here.</p>
  
  <p>Anyway, the problem with the above code is that it does work if the user is already inside the region when it adds the region to their device (ie. didEnterRegion is done). However the problem is that the method <code>didDetermineState: forRegion:</code> is also called every time one of the boundary regions is crossed as per the apple docs:</p>
  
  <blockquote>
    <p>The location manager calls this method whenever there is a boundary transition for a region. It calls this method in addition to calling the locationManager:didEnterRegion: and locationManager:didExitRegion: methods. The location manager also calls this method in response to a call to its requestStateForRegion: method, which runs asynchronously.</p>
  </blockquote>
  
  <p>Now because of this every time a region is entered, <code>didEnterRegion</code> is automatically called but then it is called again because <code>didDetermineState: forRegion:</code> is also automatically called as per the apple docs and this results in <code>didEnterRegion</code> being called again so the region is entered twice when i only want it to be entered once. How can i avoid this?</p>
  
  <p>Thanks for your help.</p>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>The solution really is so simple i was just going about it the wrong way. I had to choose to either use the 2 methods <code>didEnterRegion:</code> and <code>didExitRegion</code> or use <code>didDetermineState: forRegion</code> and create my own methods for entering and exiting the region, <strong>both should not be used</strong>. </p>
  
  <p>So i have chosen to use only the <code>didDetermineState: forRegion</code> method and my code now looks like this:</p>
  
  <p><em>Please note that with this method exit region will be called for the region if not inside and if, like me, you only want exit to happen after an enter has happened you will need some sort of method of checking if the region has already been entered (I myself used core data as i was already using this to store other aspects of the regions).</em></p>
  
  <pre><code>- (void)viewDidLoad {
      //location manager set up etc...
      for (Object *object in allObjects){
  
          CLRegion *region = [self geofenceRegion:object];
          [locationManager startMonitoringForRegion:region];
       }
  }
  
  - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
  
      [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5];
  }
  
  - (void)locationManager:(CLLocationManager *)manager
    didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
  
      if (state == CLRegionStateInside){
  
          [self enterGeofence:region];
  
      } else if (state == CLRegionStateOutside){
  
          [self exitGeofence:region];
  
      } else if (state == CLRegionStateUnknown){
          NSLog(@"Unknown state for geofence: %@", region);
          return;
      }
  }
  
  - (void)enterGeofence:(CLRegion *)geofence {
  
      //whatever is required when entered
  }
  
  - (void)exitGeofence:(CLRegion *)geofence {
  
      //whatever is required when exit
  }
  </code></pre>