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