startMonitoringForRegion vs CLRegion:containCoordinate

1.3k views Asked by At

in my IOS app I am implementing geofencing. In the current implementation I am using code like this:

  CLRegion* region3 = [[CLRegion alloc] initCircularRegionWithCenter:coordinates radius:100 identifier:@"region3"];
[self.locationManager startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyHundredMeters];

and then I am using these delegate methods:

 (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
        NSLog(@"didenterregion");

    }
    (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
        NSLog(@"didexitregion");
    }

    (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
    {NSLog(@"monitoringDidFailForRegion");}

However, this code works fine only for radius bigger than 100m.

Here are some questions:

  1. Apple says that in ios6 and above a radius between 1 and 400m is supported for devices 4s and above. Since I do not care how long it will take for the message to be viewed (like I do not care to see the message when entering the region but I do care to see at a latter if I have passed from that region once) can I use smaller radius? I am interested in something like 50m radius or smaller? (in some regions even 20m will be needed for my case).

I have also think that. Apple says that up to 20 regions could be supported. What are the advantages/ disadvantages of a sollution like this (I haven't implemented it yet but I want your opinion).

The pseudocode would be like this:

Declare the regions - save them in an array
Do not call start monitoring

And then in the delegate method:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
      for loop in all my regions {
         if ([region containsCoordinate: newLocation.coordinate])
            code for entering region
      } 
}
  1. Would it be slower?
  2. Would it consume more battery? (I think monitoring for regions is not battery consuming)?
  3. Could it be more accurate?
  4. Can I have more than 20 regions since I am not registering for monitor?

Thanks in advance.

1

There are 1 answers

2
Michael Dautermann On BEST ANSWER

1.

I suspect the second (didUpdateToLocation:-based) implementation would be more expensive (in terms of battery life) versus the first implementation, simply because you would only run the code in the first (startMonitoringForRegion:-based) implementation if and only if the device came within the radius of one of the (maximum of 20) regions you're tracking.

Whereas in the second implementation, code has to run each time there's a "didUpdateToLocation:" delegate call (which will happen fairly often) and then the code inside the delegate method will get run.

B.T.W., you say the code works fine for a radius of 100m of above, but then the Apple documentation says it should work in iOS6 with "a radius between 1 and 400m is supported for devices 4s and above."

Is your "100m" number your practical result or is it a limitation of the device you're using (something older than an iPhone 4s or an older iOS version)?

2.

Doing anything in the background does consume battery but Apple has optimized CoreLocation for this somewhat (provided you set the correct flag in your app's info.plist file)

3.

I think both will be about equally accurate, except for the fact it may take up to a few minutes for "startMonitoringForRegion:" to report that the region was entered or exited.

4.

And yeah, in the second implementation, you can have as many regions as you want to track. However, the more code you run in the background, the hotter the battery gets and the more likely it is you're draining the battery faster.