0

I need to know if I am near to a saved Geo-location in my app within a range starting at 10 Meters to 500 Meters in background. I have used startMonitoringForSignificantLocationChange but I am not getting accurate results. Instead using startupdatinglocation is giving results as accurate as 7 meters. I am planning to add a NSTimer to call startupdatinglocation every 1 minute.

Is there any other solutions?

Honey
  • 24,125
  • 14
  • 123
  • 212
  • 3
    See [Getting Location Events in the Background](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW10). You should not have to call `startUpdatingLocation` in the background. But you must request permission to keep location services going. See [location discussion here](http://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW24) – Rob May 20 '13 at 13:31
  • http://stackoverflow.com/questions/6347503/how-do-i-get-a-background-location-update-every-n-minutes-in-my-ios-application – Agent Chocks. May 20 '13 at 13:33

2 Answers2

2

First of all, please don't call startUpdatingLocation every minute. You will kill your users battery life on their devices. Location services utilizes a large amount of battery power to operate. Also, once you call startUpdatingLocation, it will run until you call stopUpdatingLocation.

There are properties you can set on CLLocationManager to configure it to your needs. Like...

@property(assign, nonatomic) CLLocationDistance distanceFilter
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy

distanceFilter description: The minimum distance (measured in meters) a device must move horizontally before an update event is generated.

desiredAccuracy can be one of the following:

kCLLocationAccuracyBestForNavigation
kCLLocationAccuracyBest;
kCLLocationAccuracyNearestTenMeters;
kCLLocationAccuracyHundredMeters;
kCLLocationAccuracyKilometer;
kCLLocationAccuracyThreeKilometers;

Depending on the configuration of your CLLocationManager object, the device will use certain geo location hardware versus others. Sometimes simply using cell tower triangulation will be sufficient and is the quickest way to get a semi accurate location. Other times it might need to utilize GPS, which will drain battery life very quickly and takes much longer to achieve a location but is in most cases much more accurate.

I would recommend starting an NSTimer, but utilize it for the opposite of what you had planned. Utilize it to stopUpdatingLocation after a reasonable amount of time if CLLocationManager isn't able to get an accurate enough location. You DO NOT want to leave location services running for ever. Having this timer set to something like 30 seconds will ensure that it is shut down after the timeout.

Also, you will need to implement the CLLocationManagerDelegate method:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

In this method you will need to check the timestamp of the location to ensure it is recent. You will also need to check the horizontalAccuracy of the location to ensure it is within the desired accuracy range. Here is an example of how to do this...

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    // Ensure we get a recent and accurate location
    NSDate * locationTimestamp = [newLocation timestamp];
    NSTimeInterval timeDifference = [locationTimestamp timeIntervalSinceNow];
    double thirtyMins = (30 * 60 * -1);
    BOOL locationTimestampIsCurrent = (timeDifference > thirtyMins);
    BOOL isAccurateLocation = (newLocation.horizontalAccuracy <= 3000.00);

    if (locationTimestampIsCurrent && isAccurateLocation) {
        NSLog(@"Shutting down location services, we have a good locaton.");
        [self stopListeningForLocation];
    } else {
        // Do nothing, let this method be called again with a new "newLocation" to check its validity.
    }
}

From iOS 6 the above method is deprecated, instead use the following delegate method:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

To get the newest location simply fetch the last object of the locations array like so:

  CLLocation *location = [locations lastObject];
Community
  • 1
  • 1
Jeremy Fox
  • 2,638
  • 1
  • 23
  • 26
  • hello there thanks for you reply :). My first question is that suppose a person has added 3 points of interest and each varies over a distance of a few meters how can i turn off the location? Since it will stop updating.. An using the timer it will turn on location but after 30 seconds it will turn off how to restart the startUpdatingLocation? – droidiphonereef May 21 '13 at 05:48
  • I want to run startUpdatingLocation every N seconds depending on the user settings 5,10,20....seconds. – droidiphonereef May 21 '13 at 06:07
  • Have you tried this approach when the app is in the background and the timer interval is more than say 5 minutes? – SleepNot Jul 09 '14 at 13:57
0

You are really starting from scratch with those questions. I suggest you follow Rob and Abhijit links. You also may benefit from experimenting with my code on Github:

TTLocationHandler Github

Dean Davids
  • 4,154
  • 2
  • 27
  • 44