Оповещения о местоположении с использованием Core Data, чтобы обойти ограничение региона CLRegion 20

У меня есть приложение, которое хранит достопримечательности (POI) в Core Data managedObjectContext. Моя цель состоит в том, чтобы получать оповещения, если currentLocation находится в пределах указанного диапазона POI в managedObjectContext. Читая о CLRegion, кажется, что количество регионов, которые можно отслеживать, ограничено 20.

Чтобы обойти ограничение на мониторинг региона, мой план игры состоит в том, чтобы просматривать мои managedObjectContext координаты широты / долготы и вычислять расстояния между POI каждый раз, когда в моем приложении срабатывает didUpdateLocations диспетчера местоположения:

- (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 только для отображения данных. В этом случае я ничего не показываю - вместо этого я просто бегаю по объектам в моем MOC, когда didUpdateLocations срабатывает, вытаскивая координаты и вычисляя расстояние. Есть идеи, как это сделать?


person Adrian    schedule 25.03.2015    source источник
comment
Я не уверен, что понимаю вопрос. Если вы не хотите отображать данные, не выполняйте код, который выводит их на экран. Какая часть не имеет смысла?   -  person Tom Harrington    schedule 26.03.2015
comment
Я обновил свой пост для дополнительных разъяснений.   -  person Adrian    schedule 26.03.2015


Ответы (1)


Я назвал свой класс LocationManager, и это одноэлементный класс. В шапке добавил свойство для NSManagedObjectContext.

.h

@property (nonatomic, weak) NSManagedObjectContext *managedObjectContext;

Мой стек Core Data находится в моем AppDelegate, поэтому я настроил метод инициализации моей реализации LocationManager, чтобы «увидеть» его:

.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);
    }
}
person Adrian    schedule 26.03.2015