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

こ雲淡風輕ζ 提交于 2019-12-12 01:47:49

问题


I have an app that stores points of interest (POIs) in a Core Data managedObjectContext. My objective is to have alerts go off if currentLocation is within a specified range of a POI in the managedObjectContext. In reading about CLRegion, it seems the amount of regions that can be monitored is capped at 20.

To get around the region monitoring cap, my game plan is to skim my managedObjectContext for latitude/longitude coordinates and compute distances between POIs every time my location manager's didUpdateLocations fires in my app:

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

}

I've only used managedObjectContext to display data. In this case, I'm not displaying anything--instead, I'm just running through the objects in my MOC when didUpdateLocations fires, pulling out coordinates and computing a distance. Any ideas how to accomplish this?


回答1:


I called my class LocationManager and it's a singleton class. In the header, I added a property for NSManagedObjectContext.

.h

@property (nonatomic, weak) NSManagedObjectContext *managedObjectContext;

My Core Data stack is in my AppDelegate, so I tweaked the init method of my LocationManager implementation to "see" it:

.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;
}

Further down, when the didUpdateLocations method fires, I added a call to [self calculateDistances], like so:

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


来源:https://stackoverflow.com/questions/29267438/location-alerts-using-core-data-to-get-around-clregion-20-region-cap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!