iOS Geofence,监控开始时如何处理内部区域?

时间:2015-05-17 00:58:09

标签: ios cllocationmanager geofencing clregion

我一直无法解决如何在调用startMonitoringForRegion时处理手机已经在某个区域内的情况?其他问题建议在requestStateForRegion内调用didStartMonitoringForRegion,然后调用方法didDetermineState: forRegion:。所以代码看起来像这样:

- (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];
    }  
}

现在显然geofenceRegion方法是我自己的,它工作正常,对象包含lat long和radius之类的东西,并且一切正常,所以这不是问题。

无论如何,上面代码的问题在于,如果用户在将区域添加到其设备时已经在区域内(即完成了didEnterRegion),它确实有效。但问题是每次根据apple docs划分其中一个边界区域时,也会调用方法didDetermineState: forRegion:

  

只要存在区域的边界过渡,位置管理器就会调用此方法。除了调用locationManager:didEnterRegion:和locationManager:didExitRegion:methods之外,它还调用此方法。位置管理器还调用此方法以响应对其requestStateForRegion:方法的调用,该方法以异步方式运行。

现在正因为每次输入某个区域时,会自动调用didEnterRegion,然后再次调用它,因为didDetermineState: forRegion:也会根据apple文档自动调用,这会导致{{1}当我只想输入一次时,再次调用该区域两次。我怎么能避免这个?

感谢您的帮助。

解决方案真的很简单我只是以错误的方式去做。我必须选择使用2种方法didEnterRegiondidEnterRegion:或使用didExitRegion并创建我自己的方法来进入和退出该区域,两者都不应该使用

所以我选择只使用didDetermineState: forRegion方法,我的代码现在看起来像这样:

请注意,使用此方法,如果不在内部,将为该区域调用退出区域,如果像我一样,您只想在输入发生后退出,则需要某种方法来检查是否该区域已经进入(我自己使用核心数据,因为我已经使用它来存储区域的其他方面)。

didDetermineState: forRegion

1 个答案:

答案 0 :(得分:4)

根本不要使用 locationManager:didEnterRegion:,因为 locationManager:didDetermineState:forRegion:为您提供触发入门代码所需的所有信息,顺便说一句,它不应该是 locationManager:didEnterRegion:,使用你自己的选择器,它不是 CLLocationManagerDelegate 协议的一部分。

另一种方法是在开始监视区域时测试区域内的位置。这个解决方案听起来不是那么简单:你需要先调用 startUpdatingLocation 来更新当前位置,因为只是读取locationManager的location属性可能会让你失去阅读或非常不准确。