Ответ 1
Для отслеживания местоположения пользователя, когда приложение не работает (т.е. ранее было завершено), существует два варианта:
-
В руководстве по программированию приложений iOS в разделе "Отслеживание местоположения пользователя":
Служба значительных изменений местоположения настоятельно рекомендуется для приложений, которым не нужны высокоточные данные о местоположении. С помощью этой службы обновления местоположения генерируются только при значительном изменении местоположения пользователей; таким образом, он идеально подходит для социальных приложений или приложений, которые предоставляют пользователю некритичную информацию о местоположении. Если приложение приостанавливается при возникновении обновления, система обрабатывает его в фоновом режиме для обработки обновления. Если приложение запускает эту службу и затем завершается, система автоматически запускает приложение, когда новое место становится доступным. Эта услуга доступна в iOS 4 и более поздних версиях, и она доступна только на устройствах, которые содержат сотовую радиостанцию.
Однако, в соответствии с ссылкой класса CLLocationManager, он не слишком точен, а обновления нечасты:
Примечание. Приложения могут ожидать уведомления, как только устройство перемещается на 500 метров или более из своего предыдущего уведомления. Он не должен ожидать уведомлений чаще, чем раз в пять минут. Если устройство может извлекать данные из сети, диспетчер местоположений гораздо чаще отправляет уведомления своевременно.
-
Мониторинг регионов работает аналогичным образом - в том числе перезапуск приложения после его завершения - но с большей точностью (в зависимости от доступности Wi-Fi сетей и сотовых вышек ):
Определенные пороговые расстояния определяются оборудованием и технологиями местоположения, которые в настоящее время доступны. Например, если Wi-Fi отключен, мониторинг области значительно менее точен. Однако для целей тестирования вы можете предположить, что минимальное расстояние составляет около 200 метров.
Наблюдение за другим регионом заключается в том, что (в соответствии с ссылкой класса CLLocationManager) уведомления о въезде и выезде в регионе могут быть получены только через 3-5 минут после пересечения региона границы.
В зависимости от реальных требований, региональный мониторинг может использоваться для получения "грубого" местоположения, а затем, когда пользователь находится в определенном регионе, запустите более точную службу GPS на диспетчере местоположений. Когда пользователь покинет интересующую вас область, отключите службу GPS, чтобы сохранить батарею и снова вернуться к службе мониторинга грубого местоположения (например, мониторинг региона). Вот базовая реализация:
SomeViewController.m
... @interface SomeViewController () <CLLocationManagerDelegate> @property (nonatomic, strong) CLLocationManager *locationManager; @property (nonatomic, strong) CLRegion *someRegion; @end @implementation SomeViewController - (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[CLLocationManager alloc] init]; CLLocationDistance radius = 10; // 10 metre sensitivity self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:@"Smithtown Dry Cleaners"]; self.locationManager.delegate = self; [self.locationManager startMonitoringForRegion:self.someRegion]; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.distanceFilter = 10; [self.locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { [self.locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { [self.locationManager stopUpdatingLocation]; } // Delegate method from the CLLocationManagerDelegate protocol. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation* location = [locations lastObject]; // If the user current location is not within the region anymore, stop updating if ([self.someRegion containsCoordinate:location.coordinate] == NO) { [self.locationManager stopUpdatingLocation]; } NSString *locationData = [NSString stringWithFormat:@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude]; NSLog(@"%@", locationData); UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertBody = locationData; localNotification.alertAction = @"Location data received"; localNotification.hasAction = YES; [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; }
Не забудьте добавить соответствующие записи в файл plist приложения, чтобы приложение работало в фоновом режиме с доступом к соответствующим ресурсам:
MyApp-Info.plist:
<key>UIBackgroundModes</key> <array> ... <string>location</string> </array> <key>UIRequiredDeviceCapabilities</key> <array> ... <string>location-services</string> <string>gps</string> </array>
В приведенном выше коде предполагается использование iOS6 и ARC