Получение расположения пользователя

Приложения используют данные расположения во многих целях, в пределах от социальной сети к службам навигации «поворот за поворотом». Они получают данные расположения через классы Базовой платформы Расположения. Эта платформа предоставляет несколько услуг, которые можно использовать, чтобы получить и контролировать текущее расположение устройства:

Для использования функций Базовой платформы Расположения необходимо соединить приложение с CoreLocation.framework в Вашем проекте XCode. Для доступа к классам и заголовкам платформы включайте #import <CoreLocation/CoreLocation.h> оператор наверху любых файлов соответствующего источника.

Для получения общей информации о классах Базовой платформы Расположения, посмотрите Базовую Ссылку Платформы Расположения.

Требование Присутствия Служб определения местоположения в приложении для iOS

Если Ваше приложение для iOS требует, чтобы службы определения местоположения функционировали должным образом, включайте UIRequiredDeviceCapabilities введите приложение Info.plist файл. App Store использует информацию в этом ключе, чтобы препятствовать тому, чтобы пользователи загрузили приложения на устройства, не содержащие перечисленные функции.

Значение для UIRequiredDeviceCapabilities массив строк, указывающих функции, которых требует Ваше приложение. Две строки относятся к службам определения местоположения:

Для получения дополнительной информации о UIRequiredDeviceCapabilities ключ, посмотрите информационную Ключевую Ссылку Списка свойств.

Получение текущего расположения пользователя

Базовая платформа Расположения позволяет Вам определить местоположение текущей позиции устройства и использовать ту информацию в Вашем приложении. Платформа сообщает о расположении устройства Вашему коду и, в зависимости от того, как Вы конфигурируете службу, также обеспечивает периодические обновления, поскольку это получает новые или улучшенные данные.

Две службы могут дать Вам текущее расположение пользователя:

Сбор данных расположения является интенсивными действиями питания. Для большинства приложений обычно достаточно установить начальное определение местоположения и затем получить обновления только периодически после этого. Независимо от важности данных расположения в Вашем приложении необходимо выбрать надлежащую службу определения местоположения и использовать его мудро, чтобы избежать истощать батарею устройства. Например:

Определение, доступны ли службы определения местоположения

Существуют ситуации, где службы определения местоположения могут не быть доступными. Например:

  • Пользователь отключает службы определения местоположения в приложении Настроек или Установках системы.

  • Пользователь отклоняет службы определения местоположения для определенного приложения.

  • Устройство находится в Авиарежиме и неспособно включить необходимые аппаратные средства.

По этим причинам рекомендуется всегда вызывать locationServicesEnabled метод класса CLLocationManager прежде, чем попытаться запустить или службы определения местоположения стандартного или существенного изменения. Если это возвращается NO и Вы пытаетесь запустить службы определения местоположения так или иначе, системные приглашения пользователь, чтобы подтвердить, должны ли быть повторно включены службы определения местоположения. Поскольку пользователь, вероятно, отключил службы определения местоположения нарочно, подсказка, вероятно, не будет приветствоваться.

Запуск стандартной службы определения местоположения

Стандартная служба определения местоположения является наиболее распространенным способом получить текущее расположение пользователя, потому что это доступно на всех устройствах и и в iOS и в OS X. Перед использованием этой службы Вы конфигурируете его путем указания желаемой точности данных расположения и расстояния, на которое нужно путешествовать прежде, чем сообщить о новом расположении. При запуске службы она использует указанные параметры для определения аппаратных средств для включения и затем продолжается для создания отчетов о событиях расположения приложению. Поскольку эта служба принимает во внимание эти параметры, это является самым подходящим для приложений, для которых нужно больше тонкозернистого управления поставкой событий расположения. Точность стандартной службы определения местоположения необходима приложениям навигации или любому приложению, требующему данных расположения высокой точности или регулярного потока обновлений. Поскольку эта служба обычно требует, чтобы отслеживающие расположение аппаратные средства были включены в течение более длительных промежутков времени, более высокое использование питания может закончиться.

Для использования стандартной службы определения местоположения создайте экземпляр CLLocationManager класс и конфигурирует desiredAccuracy и distanceFilter свойства. Чтобы начать получать уведомления расположения, присвойте делегата в объекте и вызовите startUpdatingLocation метод. Поскольку данные расположения становятся доступными, менеджер расположения уведомляет его присвоенный объект делегата. Если обновление информации о местоположении было уже поставлено, можно также получить новые данные расположения непосредственно от CLLocationManager объект, не ожидая нового события, которое будет поставлено. Для остановки поставки обновлений информации о местоположении вызовите stopUpdatingLocation метод менеджера расположения объект.

Перечисление 1-1 показывает выборочный метод, конфигурирующий менеджера расположения по использованию. Выборочный метод является частью класса, кэширующего его менеджера расположения объект в задействованной переменной для более позднего использования. (Класс также соответствует CLLocationManagerDelegate протокол и так действует как делегат к менеджеру расположения.), Поскольку для приложения не нужны точные данные расположения, оно конфигурирует службу определения местоположения, чтобы сообщить об общей области пользователя и отправить уведомления только, когда пользователь перемещает по крайней мере половину километра.

Перечисление 1-1  , Начинающее стандартную службу определения местоположения

- (void)startStandardUpdates
{
    // Create the location manager if this object does not
    // already have one.
    if (nil == locationManager)
        locationManager = [[CLLocationManager alloc] init];
 
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
 
    // Set a movement threshold for new events.
    locationManager.distanceFilter = 500; // meters
 
    [locationManager startUpdatingLocation];
}

Код для получения обновлений информации о местоположении от этой службы показан в Получении Данных Расположения от Службы.

Запуск службы определения местоположения существенного изменения

Служба определения местоположения существенного изменения обеспечивает точность, это достаточно хорошо для большинства приложений и представляет альтернативу экономии электроэнергии стандартной службе определения местоположения. Служба использует Wi-Fi для определения расположения пользователя и изменений отчета в том расположении, позволяя системе управлять использованием питания намного более настойчиво, чем это могло иначе. Служба определения местоположения существенного изменения может также разбудить приложение для iOS, в настоящее время приостанавливающееся или не выполнение для поставки новых данных расположения.

Для использования службы определения местоположения существенного изменения создайте экземпляр CLLocationManager класс, присвойте делегата в нем и вызовите startMonitoringSignificantLocationChanges метод как показано в Перечислении 1-2. Поскольку данные расположения становятся доступными, менеджер расположения уведомляет его присвоенный объект делегата. Если обновление информации о местоположении было уже поставлено, можно также получить новые данные расположения непосредственно от CLLocationManager объект, не ожидая нового события, которое будет поставлено.

Перечисление 1-2  , Начинающее службу определения местоположения существенного изменения

- (void)startSignificantChangeUpdates
{
    // Create the location manager if this object does not
    // already have one.
    if (nil == locationManager)
        locationManager = [[CLLocationManager alloc] init];
 
    locationManager.delegate = self;
    [locationManager startMonitoringSignificantLocationChanges];
}

Как со стандартной службой определения местоположения, данные расположения поставлены объекту делегата, как описано в Получении Данных Расположения от Службы. Для остановки службы определения местоположения существенного изменения вызовите stopMonitoringSignificantLocationChanges метод.

Если Вы оставляете выполнение службы определения местоположения существенного изменения, и Ваше приложение для iOS впоследствии приостановлено или завершено, служба автоматически будит Ваше приложение, когда поступают новые данные расположения. Во время пробуждения приложение помещается в фон, и Вам дают мелкую сумму времени (приблизительно 10 секунд), чтобы вручную перезапустить службы определения местоположения и обработать данные расположения. (Необходимо вручную перезапустить службы определения местоположения в фоновом режиме, прежде чем любые незаконченные обновления информации о местоположении смогут быть поставлены, как описано в Знании, Когда Запустить Службы определения местоположения.), Поскольку Ваше приложение в фоновом режиме, оно должно выполнить минимальную работу и избежать любых задач (таких как запросы сети), который мог бы препятствовать тому, чтобы оно возвратилось, прежде чем истечет выделенное время. Если это не сделает, то Ваше приложение будет завершено. Если для приложения для iOS нужно больше времени для обработки данных расположения, это может запросить больше фонового времени выполнения с помощью beginBackgroundTaskWithName:expirationHandler: метод UIApplication класс.

Получение данных расположения от службы

Путем Вы получаете события расположения, то же, используете ли Вы стандарт или службу определения местоположения существенного изменения для получения их. Начиная в OS X v10.9 и iOS 6, менеджер расположения сообщает о событиях locationManager:didUpdateLocations: метод его делегата, когда они становятся доступными. (В более ранних версиях обеих операционных систем менеджер расположения сообщает о событиях locationManager:didUpdateToLocation:fromLocation: метод.), Если существует ошибка при получении события, вызовы диспетчера расположения locationManager:didFailWithError: метод его делегата вместо этого.

Перечисление 1-3 показывает метод делегата для получения событий расположения. Поскольку менеджер расположения возражает, иногда возвращает кэшируемые события, рекомендуется проверить метку времени любых событий расположения, которые Вы получаете. (Может потребоваться несколько секунд для получения грубого расположения, фиксируют, таким образом, старые данные просто служат способом отразить последнее известное расположение.) В этом примере метод выбрасывает любые события, которые составляют больше чем пятнадцать секунд, старых под предположением, что события до того возраста, вероятно, будут достаточно хороши. При реализации приложения навигации Вы могли бы хотеть понизить порог.

Перечисление 1-3  , Обрабатывающее входящее событие расположения

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
      didUpdateLocations:(NSArray *)locations {
    // If it's a relatively recent event, turn off updates to save power.
   CLLocation* location = [locations lastObject];
   NSDate* eventDate = location.timestamp;
   NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
   if (abs(howRecent) < 15.0) {
      // If the event is recent, do something with it.
      NSLog(@"latitude %+.6f, longitude %+.6f\n",
              location.coordinate.latitude,
              location.coordinate.longitude);
   }
}

В дополнение к метке времени объекта расположения можно также использовать точность, о которой сообщает тот объект определить, хотите ли Вы принять событие. Поскольку это получает более точные данные, служба определения местоположения может возвратить дополнительные события со значениями точности, отражающими улучшения соответственно. Выбрасывание менее точных событий означает, что Ваше приложение тратит впустую меньше времени на события, которые не могут использоваться эффективно так или иначе.

Знание, когда запустить службы определения местоположения

Приложения, использующие службы определения местоположения, не должны запускать те службы, пока они не необходимы. За немногим исключением избегите стартовых служб определения местоположения сразу во время запуска или прежде чем могли бы обоснованно использоваться такие службы. Иначе Вы могли бы вызвать вопросы в голове пользователя о том, как Ваше приложение использует данные расположения. Пользователь знает, когда Ваше приложение запускает службы определения местоположения, потому что в первый раз Ваше приложение запускает службу, системные приглашения пользователь для разрешения использовать его. При ожидании, пока пользователь не выполняет фактически требующую задачу те службы помогают построить доверительные отношения, что приложение использует их соответственно. Другой способ построить доверительные отношения состоит в том, чтобы включать NSLocationUsageDescription введите свое приложение Info.plist файл и набор значение того ключа к строке, описывающей, как Ваше приложение намеревается использовать данные расположения.

Если Вы контролируете области или используете службу определения местоположения существенного изменения в Вашем приложении, существуют ситуации, где необходимо запустить службы определения местоположения во время запуска. Когда новые события расположения поступают, приложения с помощью тех служб могут быть завершены и впоследствии повторно запущены. Несмотря на то, что само приложение повторно запускается, службы определения местоположения не запускаются автоматически. Когда приложение повторно запускается из-за обновления информации о местоположении, словарь опций запуска передал Вашему application:willFinishLaunchingWithOptions: или application:didFinishLaunchingWithOptions: метод содержит UIApplicationLaunchOptionsLocationKey ключ. Присутствие того ключа сигнализирует, что новые данные расположения ожидают, чтобы быть поставленными Вашему приложению. Для получения тех данных необходимо создать новое CLLocationManager возразите и перезапустите службы определения местоположения, что у Вас было выполнение до завершения Вашего приложения. Когда Вы перезапускаете те службы, менеджер расположения поставляет все незаконченные обновления информации о местоположении его делегату.

Получение событий расположения в фоновом режиме (только iOS)

iOS поддерживает поставку событий расположения к приложениям, приостановленным или больше выполнение. Поставка событий расположения в фоновом режиме поддерживает приложения, функциональности которых повредили бы без них, поэтому сконфигурировала бы Ваше приложение для получения фоновых событий только, когда выполнение так предоставляет материальное преимущество пользователю. Например, приложение навигации «поворот за поворотом» должно отследить позицию пользователя в любом случае и уведомить пользователя, когда пора сделать следующий поворот. Если Ваше приложение может суметь обойтись альтернативными средними значениями, такими как контроль области, оно должно сделать так.

У Вас есть многократные опции для получения фоновых событий расположения, и у каждого есть преимущества и недостатки относительно потребляемой мощности и точности размещения. Каждый раз, когда возможно, приложения должны использовать службу определения местоположения существенного изменения (описанный в Запуске Службы определения местоположения Существенного изменения), который может использовать Wi-Fi для определения позиции пользователя и использует наименьшее количество суммы питания. Но если Ваше приложение требует более высоких данных расположения точности, можно сконфигурировать его как фоновое приложение расположения и использовать стандартную службу определения местоположения.

Используя стандартную службу определения местоположения в фоновом режиме

приложения для iOS могут использовать стандартную службу определения местоположения в фоновом режиме, если они предоставляют услуги, требующие непрерывных обновлений информации о местоположении. В результате эта возможность является самой подходящей для приложений, помогающих пользователю в навигации - и связанные с фитнесом действия. Для включения этой возможности в приложении включите возможность Фоновых режимов в проекте XCode (расположенный на вкладке Capabilities проекта) и включите режим Обновлений информации о местоположении. Код, который Вы пишете, чтобы запустить и остановить стандартные службы определения местоположения, неизменен.

Когда приложение находится на переднем плане, работает в фоновом режиме или приостановлено, система поставляет обновления информации о местоположении до фоновых приложений расположения. В случае приостановленного приложения система будит приложение, поставляет обновление делегату менеджера расположения, и затем возвращает приложение состоянию ожидания как можно скорее. В то время как это работает в фоновом режиме, Ваше приложение должно выполнить как можно меньше работы для обработки новых данных расположения.

Когда службы определения местоположения включены, iOS должен сохранить аппаратные средства расположения включенными так, чтобы они могли собрать новые данные. Хранение аппаратного выполнения расположения ухудшает время работы от батареи, и необходимо всегда останавливать службы определения местоположения в приложении каждый раз, когда Вам не нужны получающиеся данные расположения.

Если необходимо использовать службы определения местоположения в фоновом режиме, можно помочь Базовому Расположению поддержать хорошее время работы от батареи для устройства пользователя путем предпринятия дополнительных шагов при конфигурировании менеджера расположения объект:

  • Удостоверьтесь менеджер расположения pausesLocationUpdatesAutomatically свойство установлено в YES. Когда это свойство установлено в YES, Базовые обновления информации о местоположении пауз Расположения (и выключает аппаратные средства расположения) каждый раз, когда они целесообразны для этого такой как тогда, когда пользователь вряд ли будет перемещаться так или иначе. (Базовое Расположение также приостанавливается, обновляет, когда оно не может получить расположение, фиксируют.)

  • Присвойте надлежащее значение менеджеру расположения activityType свойство. Значение в этом свойстве помогает менеджеру расположения определить, когда безопасно приостановить обновления информации о местоположении. Для приложения, обеспечивающего автомобильную навигацию поворота по очереди, устанавливая свойство в CLActivityTypeAutomotiveNavigation заставляет менеджера расположения приостанавливать события только, когда пользователь не перемещает значительное расстояние в течение времени.

  • Вызовите allowDeferredLocationUpdatesUntilTraveled:timeout: метод, когда это возможно, для задержки поставки обновлений до более позднего времени, как описано в Задержке Обновлений информации о местоположении, В то время как Приложение в фоновом режиме.

Когда менеджер расположения приостанавливает обновления информации о местоположении, это уведомляет, что его делегат возражает путем вызова его locationManagerDidPauseLocationUpdates: метод. Когда менеджер расположения возобновляет обновления, это вызывает делегата locationManagerDidResumeLocationUpdates: метод. Можно использовать эти методы делегата выполнить задачи или скорректировать поведение приложения. Например, когда обновления информации о местоположении приостанавливаются, Вы могли бы использовать уведомление делегата, чтобы сохранить данные на диск или остановить обновления информации о местоположении в целом. Приложение навигации посреди направлений поворота по очереди могло бы предложить пользователю и спросить, должна ли навигация быть отключена временно.

Задержка обновлений информации о местоположении, в то время как приложение в фоновом режиме

Когда приложение в фоновом режиме, в iOS 6 и позже, можно задержать поставку обновлений информации о местоположении. Когда приложение могло обработать данные расположения позже без любых проблем, рекомендуется использовать эту функцию. Например, приложение фитнеса, отслеживающее расположение пользователя на походном маршруте, могло задержать обновления, пока пользователь не увеличивает определенное расстояние или пока определенная сумма времени не протекла и затем обрабатывает обновления одновременно. Задержка обновлений экономит электроэнергию путем разрешения сну приложения в течение более длительных промежутков времени. Поскольку задержка обновлений информации о местоположении требует присутствия аппаратных средств GPS на целевом устройстве, несомненно, вызовут deferredLocationUpdatesAvailable метод класса CLLocationManager класс, чтобы определить, поддерживает ли устройство задержанные обновления информации о местоположении.

Вызовите allowDeferredLocationUpdatesUntilTraveled:timeout: метод CLLocationManager класс, чтобы начать задерживать обновления информации о местоположении. Как показано в Перечислении 1-4, обычное место для вызова этого метода находится в locationManager:didUpdateLocations: метод Вашего менеджера расположения делегирует объект. Этот метод показывает, как демонстрационное приложение пешего туризма могло бы задержать обновления информации о местоположении, пока пользователь не увеличивает минимальное расстояние. Препятствовать тому, чтобы себя вызвал allowDeferredLocationUpdatesUntilTraveled:timeout: метод многократно, делегат использует внутреннее свойство, чтобы отследить, были ли уже задержаны обновления. Это устанавливает свойство в YES в этом методе и задерживает его к NO когда заканчиваются задержанные обновления.

Перечисление 1-4  , Задерживающее обновления информации о местоположении

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
      didUpdateLocations:(NSArray *)locations {
   // Add the new locations to the hike
   [self.hike addLocations:locations];
 
   // Defer updates until the user hikes a certain distance
   // or when a certain amount of time has passed.
   if (!self.deferringUpdates) {
      CLLocationDistance distance = self.hike.goal - self.hike.distance;
      NSTimeInterval time = [self.nextAudible timeIntervalSinceNow];
      [locationManager allowDeferredLocationUpdatesUntilTraveled:distance
                                                         timeout:time];
   self.deferringUpdates = YES;
   }
}

Когда условие Вы указали в allowDeferredLocationUpdatesUntilTraveled:timeout: метод встречен, вызовы диспетчера расположения locationManager:didFinishDeferredUpdatesWithError: метод его делегата возражает, чтобы сообщить, что он прекратил задерживать поставку обновлений информации о местоположении. Вызовы диспетчера расположения этот метод делегата точно один раз в течение каждого раза Ваше приложение вызывают allowDeferredLocationUpdatesUntilTraveled:timeout: метод. После задержанного конца обновлений менеджер расположения продолжает, чтобы поставить любые обновления информации о местоположении Вашему делегату locationManager:didUpdateLocations: метод.

Можно остановить отсрочку обновлений информации о местоположении явно путем вызова disallowDeferredLocationUpdates метод CLLocationManager класс. Когда Вы вызываете этот метод или останавливаете обновления информации о местоположении в целом с помощью stopUpdatingLocation метод, вызовы диспетчера расположения Ваш делегат locationManager:didFinishDeferredUpdatesWithError: метод для сообщения, который задержал обновления, действительно остановился.

Если менеджер расположения встречается с ошибкой и не может задержать обновления информации о местоположении, можно получить доступ к причине ошибки, когда Вы реализуете locationManager:didFinishDeferredUpdatesWithError: метод делегата. Для списка возможных ошибок, которые могут быть возвращены — и что, во всяком случае, Вы можете для разрешения их — посмотрите CLError константы в Базовой Ссылке Констант Расположения.

Подсказки для сохранения заряда батареи

Получение данных расположения в основанном на iOS устройстве может потребовать большого количества питания. Поскольку для большинства приложений не нужны службы определения местоположения для выполнения все время, выключая службы определения местоположения, когда они не необходимы, самый простой способ сэкономить электроэнергию.