使用核心数据绕过 CLRegion 20 区域上限的位置警报

Location alerts using Core Data to get around CLRegion 20 region cap

我有一个应用程序可以在核心数据中存储兴趣点 (POI) managedObjectContext。如果 currentLocationmanagedObjectContext 中指定的 POI 范围内,我的 objective 会发出警报。在阅读 CLRegion 时,似乎可以监控的区域数量上限为 20。

为了避开区域监控上限,我的游戏计划是在每次我的位置管理器的 didUpdateLocations 触发时浏览我的 managedObjectContext 以获得 latitude/longitude 坐标并计算 POI 之间的距离应用程序:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    NSLog(@"LocationManager Latitude %+.6f, Longitude %+.6f\n",
          location.coordinate.latitude,
          location.coordinate.longitude);
    // TODO: compute distances between objects in managedObjectContext
    [self calculateDistances];
    self.currentLocation = location;
}

// method to compute distances
- (void) calculateDistances {

    // for POI in managedObjectContext, do the following
    CLLocation *locA = [[CLLocation alloc] initWithLatitude:self.currentLocation.coordinate.latitude longitude:self.currentLocation.coordinate.longitude];

    CLLocation *locB = [[CLLocation alloc] initWithLatitude:POIlatitude longitude:POIlongitude];

    CLLocationDistance distance = [locA distanceFromLocation:locB];

    if (distance < 1000) {
        // popup alert
    }

}

我只使用 managedObjectContext 来显示数据。在这种情况下,我没有显示任何东西——相反,当 didUpdateLocations 触发时,我只是 运行 通过我的 MOC 中的对象,提取坐标并计算距离。有什么想法可以实现吗?

我打电话给我的 class LocationManager,它是一个单身人士 class。在header中,我为NSManagedObjectContext添加了一个属性。

.h

@property (nonatomic, weak) NSManagedObjectContext *managedObjectContext;

我的核心数据堆栈在我的 AppDelegate 中,所以我将 LocationManager 实现的 init 方法调整为 "see" 它:

.m

- (id)init {
    self = [super init];
    if (!self.locationManager) {
        // This is so I can get a reference to the managedObjectContext
        AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        self.managedObjectContext = appDelegate.managedObjectContext;

        self.locationManager = [[CLLocationManager alloc]init];

        if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [self.locationManager requestAlwaysAuthorization];
        }

        self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        self.locationManager.distanceFilter = 100; // meters
        self.locationManager.delegate = self;
    }
    return self;
}

更进一步,当 didUpdateLocations 方法触发时,我添加了对 [self calculateDistances] 的调用,如下所示:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    NSLog(@"LocationManager Latitude %+.6f, Longitude %+.6f\n",
          location.coordinate.latitude,
          location.coordinate.longitude);
    [self calculateDistances];
    self.currentLocation = location;
}

// method to compute distances
- (void) calculateDistances {

    NSError *error;
    NSFetchRequest *coordinateRetrieval = [[NSFetchRequest alloc]initWithEntityName:@"PointOfInterest"];
    NSArray *pois = [self.managedObjectContext executeFetchRequest:coordinateRetrieval error:&error];

    for (PointOfInterest *venue in poi) {
        CLLocation *locA = self.currentLocation;
        CLLocation *locB = [[CLLocation alloc]initWithLatitude:[venue.latitude doubleValue] longitude:[venue.longitude doubleValue]];
        CLLocationDistance distance = [locA distanceFromLocation:locB];

        if (distance < 1000) {
            // popup alert
        }
        NSLog(@"The distance from currentLocation to venue is %lf meters", distance);
    }
}