2

I have implemented Region monitoring for Geofencing. Now i need to check if the user still in the same region after 1 min. I have added NSTimer for 1 min and checked the didDetermineState. It works fine for Foreground and Background modes.

Its not working when app got killed as the NSTimer wont work. Is there any way to get notified if the user still in same region after some time?

Any help will be really appreciated. Thanks!

Cintu
  • 913
  • 2
  • 16
  • 32
  • AFAIK, if you app is user-quit then the OS would no longer pass the CoreLocation delegate callbacks. If the app was suspended then the OS would pass the delegate callbacks. NSTimer works in neither suspended nor user-quit. – mfaani Oct 26 '17 at 10:54
  • @Honey - Region monitoring didEnterLocation, didExitLocation and didDetermineState delegates works even after user-quit application. – Cintu Oct 26 '17 at 11:47
  • My Above question will work in android, i want to do similar in iOS – Cintu Oct 26 '17 at 11:48
  • I have tried with timer, can we do anything with notifications? – Cintu Oct 26 '17 at 11:49
  • "Region monitoring didEnterLocation, didExitLocation and didDetermineState delegates works even after user-quit application" you mean it works for iOS? or for Android? – mfaani Oct 26 '17 at 13:19
  • You are right, my bad. See [here](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html) and follow where it says: "**Note:** If your app is terminated either by a user or by the system" – mfaani Oct 26 '17 at 13:22

2 Answers2

1

since didUpdateLocations get called in continues manner while the App is terminated under authorizedAlways.

Instead of the Timer you can rely on the Date and didUpdateLocations as follows:

var locatonTimestamp:Date?

override func viewDidLoad()
{
    super.viewDidLoad()
    self.locatonTimestamp = Date()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    if let _ = locations.first
    {
        let now = Date()
        let interval = (self.locatonTimestamp != nil) ? now.timeIntervalSince(self.locatonTimestamp!) : 0

        //it will pass this condition every 60 secs
        if self.locatonTimestamp == nil || interval >= 60
        {
            self.locatonTimestamp = now
            //do your region checking here
        }
    }
}

Update

In Objective-c:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.locatonTimestamp = [NSDate new];
}

-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    if (locations.count > 0)
    {
        NSDate *now = [NSDate new];
        NSTimeInterval interval = (self.locatonTimestamp != nil) ? [now timeIntervalSinceDate:self.locatonTimestamp] : 0;

        //it will pass this condition every 60 secs
        if (self.locatonTimestamp == nil || interval >= 60)
        {
            self.locatonTimestamp = now;
            //do your region checking here
        }
    }
}
Ayman Ibrahim
  • 1,359
  • 15
  • 24
  • @Cintu Yes if you have authorizedAlways, and you use Significant Location Changes, your app will get woken up, and didupdatelocations will got called. – Ayman Ibrahim Oct 27 '17 at 19:08
  • But for the above solution i cant use Significant Location Changes rite? Then how to make it work? – Cintu Oct 30 '17 at 04:41
0

"Is there any way to get notified if the user still in same region after some time?"

Not to my knowledge. Regions are managed by the OS, Timers are managed by the app. Timers are killed if the app is terminated. Regions stay alive.

A possible workaround:

Create a region, but turn on its notifyOnExit. And as long as you don't get that callback you can assume you're still in that geofence and just try to do something using that callback, like if you get that callback in less than 10 minutes then do something if you get that callback in 10-20 minutes then do something else, and if you get that callback in more than 20 minutes then do some other thing and if you never got that callback then well it means you're still in that region, but unfortunately you won't be able to get a callback for that one :/

Having that said geofence aren't entirely reliable. Though this question is a bit old. I'm not sure how valid it is.

Additionally your timer won't work if app is suspended. What you can do is keep the app alive in the background using core-location, but use it with 3kilometers accuracy (to preserve battery but still keep the app alive) and then create a timer. Not a really great solution though. And maybe Apple would reject it.

mfaani
  • 33,269
  • 19
  • 164
  • 293