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

根据用户当前位置区域监控,删除iOS7中的监控区域,ios,core-location,geofencing,region-monitoring,Ios,Core Location,Geofencing,Region Monitoring,我正在从事这样一个项目,其中应用程序可以做以下事情: 用户选择半径(10米到1000米),然后按“go”按钮转到下一个viewController 在这里,应用程序抓取用户当前位置,并根据当前位置和选定半径启动“区域监控” 如果用户越过特定边界(10米到1000米),则会发出“ExitRegion”警报消息。并根据用户新的当前位置重新启动“区域监控”。应用程序一直都在这样做,前台和后台模式都是如此。我设法做到了&它工作得很好 但现在由于区域数量的限制,通过“区域监控”进行监控,我想在创建新的“监

我正在从事这样一个项目,其中应用程序可以做以下事情:

  • 用户选择半径(10米到1000米),然后按“go”按钮转到下一个viewController
  • 在这里,应用程序抓取用户当前位置,并根据当前位置和选定半径启动“区域监控”
  • 如果用户越过特定边界(10米到1000米),则会发出“ExitRegion”警报消息。并根据用户新的当前位置重新启动“区域监控”。应用程序一直都在这样做,前台和后台模式都是如此。我设法做到了&它工作得很好
  • 但现在由于区域数量的限制,通过“区域监控”进行监控,我想在创建新的“监控区域”后删除每个“监控区域”。所以它应该是这样发生的:

    • 根据用户当前位置启动区域监视
    • 退出特定区域&并获取“退出区域”警报消息
    • 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]];
    }
    
    我为RemovingRegion设置了
    flagForRemovingRegion
    ,这样它就不会试图删除应用程序开头的“监控区域”。因为一开始它是空的。 如果有人能理解我的问题或有任何建议,请回复。
    提前谢谢。祝您度过愉快的一天。

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

    [locationManager stopMonitoringForRegion:[[[locationManager monitoredRegions] allObjects] objectAtIndex:0]];
    
    您必须遍历此集合才能找到您的区域或使用NSPredicate对其进行过滤,但为什么不在
    didExitRegion
    方法中停止它呢

    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        // your code here
    
        [manager stopMonitoringForRegion:region];
    }
    

    正如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];
    

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

    谢谢您的评论。我试着用它。将
    [manager stop monitoringforregion:region]放入didexitreon
    方法中,在
    [自我监控区域]之前
    并进行了测试,但它不起作用:(很抱歉延迟回复。感谢您对
    监控区域NSSet:
    发表我的看法,我认为使用
    唯一标识
    监控也会更加具体和准确。您能告诉我应该去哪里,或者如何做这项工作吗?如果您能提供一些关于此功能的链接或教程指南,那将非常有用。)呃。因为你上面给出的代码,我不太清楚。再次感谢。保持健康。:)嗨。register函数来自苹果的文档,它非常简单,它将基于两个参数(一个mkoverlay和一个nsstring标识符)开始监视一个区域。我使用UUID只是为了生成一个唯一的字符串。您还有更多的工作要做,比如继续跟踪您的受监控ID,以便能够在受监控区域nsset中找到它们,等等。好的,请理解。因为你在使用它,我只想问你,在我的观点中(我在谈论我在我的文章中提出的观点),它是否可能完美地完成?现在我使用的应用程序仍然是基于用户当前位置的简单区域监控。但它并没有完美地给出确切的现有地区信息。谢谢。IOS 7.1看起来更精确,但并不完美。在IOS 7.1之前,我在当前位置创建的区域有问题,然后第一次退出没有计算在内,现在看起来还可以。还要注意位置管理器及其委托,在共享实例类上声明didEnter/didExit会很好,这将是locationmanager对象的de-delegate。Hey@CalinChitu只是想问您何时调用此方法?-(void)RegisterRegionWithCircularVerlay:(MKCircle*)覆盖和标识符:(NSString*)标识符{}。我正在与CoreLocation合作,我已经用上面的Apple文档方法注册了一个区域,但它没有被调用。