问题
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