根据用户当前位置区域监控,删除iOS7中的监控区域

时间:2014-02-25 07:55:34

标签: ios core-location geofencing region-monitoring

我正在开展这样一个应用程序执行以下操作的项目:

  1. 用户选择一个半径(10米到1000米)并按“开始”按钮转到下一个viewController
  2. 此处应用程序抓取用户当前位置并根据具有所选半径的当前位置启动“区域监控”
  3. 如果用户越过某个边界(10米到1000米),则会发出“ExitRegion”警告消息。并根据用户新的当前位置再次启动“区域监控”。应用程序一直在这样做,包括前台和后台模式。我设法做到了&它工作得很好。
  4. 但是现在为了限制区域数量,通过“区域监控”进行监控,我希望在创建新区域后删除每个“受监控区域”。所以它应该像:

    • 根据用户当前位置启动区域监控
    • 退出某个地区&并获得“退出区域”警报消息
    • stopMonitoringForRegion阵列
    • 删除此“受监控区域”
    • 再次启动基于用户当前位置的区域监控
    • 退出某个地区&并获得“退出区域”警报消息
    • stopMonitoringForRegion阵列
    • 删除此“受监控区域”

    这应该是这样的。我正在尝试这个,但它无法正常工作。

    这是我的代码:

    -(void)startLocationServices
    {
        if (self.locationManager == nil)
        {
            self.locationManager = [CLLocationManager new];
        }
        [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
        [self.locationManager setDelegate:self];
        [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
        //[self.locationManager startUpdatingLocation];
    }
    
    -(void) monitoringRegion
    {
        if (flag == 0)
        {
            if (flagForRemovingRegion == 1)
            {
                // Remove monitored region from "monitoredRegions" array after monitor 5 regions
                [self removingMonitoredRegion];
            }
    
            CLLocationCoordinate2D center = CLLocationCoordinate2DMake(locationManager.location.coordinate.latitude, locationManager.location.coordinate.longitude);
    
            CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:myval identifier:@"Test"];
            CLLocationDegrees radius = myval;
    
            if (radius > self.locationManager.maximumRegionMonitoringDistance)
            {
                radius = self.locationManager.maximumRegionMonitoringDistance;
            }
            [self.locationManager startMonitoringForRegion:region];
    
            flag = 1;
            flagForRemovingRegion = 1;
            self.availabilityTextView.text = [@"Your selected Radius:" stringByAppendingFormat:@"%i", self.myval];
        }
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        flag = 0;
        [self startLocationServices];
        [self monitoringRegion];
    }
    
    -(void) removingMonitoredRegion
    {
        [locationManager stopMonitoringForRegion:[[[locationManager monitoredRegions] allObjects] objectAtIndex:0]];
    
    
    }
    
    - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
    {
    //    // regions are stored by system
        self.threeTextView.text = [@"Regions: \n\n" stringByAppendingFormat:@"%@", [[self.locationManager monitoredRegions] allObjects]];
    
        UIAlertView *alertViewOne = [[UIAlertView alloc] initWithTitle:@"Status" message:@"Region Monitoring started." delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
    
        [alertViewOne show];
    }
    
    - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        UIAlertView *alertViewTwo = [[UIAlertView alloc] initWithTitle:@"Status" message:@"You Enter the region" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
    
        [alertViewTwo show];
        self.availabilityTextView.text = @"You enter the region!";
    }
    
    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        UIAlertView *alertViewThree = [[UIAlertView alloc] initWithTitle:@"Status" message:@"You Exit the region" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
    
        [alertViewThree show];
        flag = 0;
        self.availabilityTextView.text = @"You exit the region!";
        [self monitoringRegion];
    }
    
    - (void) locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
    {
        self.availabilityTextView.text = [@"\nError:" stringByAppendingFormat:@"%@", [error localizedDescription]];
    }
    

    我设置了flagForRemovingRegion,因此它不会尝试删除应用开头的“受监控区域”。因为在开始时它是NULL。 如果有人能理解我的问题或有任何建议请回复。 提前致谢。祝你有愉快的一天。

2 个答案:

答案 0 :(得分:1)

您尝试从NSSet中删除第一个区域,但实际上NSSet是无序集合,因此在您的情况下它不正确。

[locationManager stopMonitoringForRegion:[[[locationManager monitoredRegions] allObjects] objectAtIndex:0]];

您必须遍历此集以查找您的区域或使用NSPredicate过滤它,但为什么不在didExitRegion方法中停止它?

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    // your code here

    [manager stopMonitoringForRegion:region];
}

答案 1 :(得分:1)

正如Apple文档所述,关于受监控区域NSSet:

  

此集合中的对象可能不一定是您的对象   在注册时指定。只有区域数据本身   由系统维护。因此,唯一的方法是唯一识别   已注册的区域正在使用其标识符属性。

查看我在应用中注册/管理区域的示例:

- (void)registerRegionWithCircularOverlay:(MKCircle*)overlay andIdentifier:(NSString*)identifier {

    // If the overlay's radius is too large, registration fails automatically,
    // so clamp the radius to the max value.
    CLLocationDegrees radius = overlay.radius;
    if (radius > sharedInst.locationManager.maximumRegionMonitoringDistance) {
        radius = sharedInst.locationManager.maximumRegionMonitoringDistance;
    }
    // Create the geographic region to be monitored.
    CLCircularRegion *geoRegion = [[CLCircularRegion alloc]
                                   initWithCenter:overlay.coordinate
                                   radius:radius
                                   identifier:identifier];
    if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
        if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
            NSLog(@"we can monitor");
            Region* reg = [[Region alloc] init];
            reg.myRegion = geoRegion;
            [sharedInst.regionsDict setObject:reg forKey:identifier];
            [sharedInst.locationManager startMonitoringForRegion:geoRegion];

            CLGeocoder *coder = [[CLGeocoder alloc]init] ;
            CLLocation *myLocation = [[CLLocation alloc]initWithLatitude:geoRegion.center.latitude longitude:geoRegion.center.longitude];

            [coder reverseGeocodeLocation:myLocation completionHandler:
             ^(NSArray *placemarks, NSError *error){
                 CLPlacemark *placemark= [placemarks objectAtIndex:0];
                 reg.myName = [NSString stringWithFormat:@"%@, %@", placemark.locality, placemark.thoroughfare];
                 NSLog(@"we did monitor: %@", reg.myName);
                 [sharedInst saveData];
             }];

        }
}

添加新区域:

   NSString* locId = [NSString stringWithFormat:@"KCC: %@", [[NSUUID UUID] UUIDString]];
   [self registerRegionWithCircularOverlay:circleOverlay andIdentifier:locId];

您必须找到使用标识符管理它们的方法。