Мобильная разработка

Службы местоположения не работают в iOS 8: решение проблемы

Решение проблемы, когда CLLocationManager не возвращает координаты и приложение не отображается в настройках iOS 8. Требуемые ключи Info.plist и методы авторизации.

6 ответов 2 просмотра

Службы местоположения не работают в iOS 8: приложение не отображается в настройках и CLLocationManager не возвращает координаты

Мое приложение, которое работало корректно на iOS 7, перестало работать после обновления до iOS 8 SDK. Проблема заключается в следующем:

  • CLLocationManager не возвращает местоположение
  • Приложение не отображается в разделе “Настройки” -> “Службы местоположения”

Я уже пытался найти решение этой проблемы через поиск в Google, но не нашел релевантной информации. Какие возможные причины могут вызывать эту проблему и как ее исправить?

Проблемы с сервисами местоположения в iOS 8 возникают из-за фундаментальных изменений в авторизации местоположения, требующих добавления специальных ключей в Info.plist и вызова методов авторизации перед использованием CLLocationManager. Основная причина, по которой приложение не отображается в настройках и не возвращает координаты, заключается в том, что iOS 8 больше не автоматически запрашивает разрешение на доступ к местоположению без явного запроса от приложения.


Содержание


Основные проблемы с сервисами местоположения в iOS 8

Проблемы с сервисами местоположения в iOS 8 стали одной из самых распространенных сложностей для разработчиков, обновляющих свои приложения с iOS 7. Основная проявляется в двух формах: CLLocationManager не возвращает координаты, а само приложение не отображается в разделе “Настройки” -> “Конфиденциальность” -> “Службы местоположения”. Это происходит из-за фундаментальных изменений в том, как iOS 8 обрабатывает авторизацию доступа к данным местоположения.

В iOS 7 система автоматически запрашивала разрешение у пользователя при первом использовании CLLocationManager. Однако в iOS 8 Apple изменила этот подход, введя явный механизм авторизации. Теперь разработчики должны не только добавить соответствующие ключи в Info.plist, но и явно вызвать методы запроса разрешения перед тем, как начать обновлять местоположение.

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


Требования к авторизации в iOS 8: ключи Info.plist

Для корректной работы сервисов местоположения в iOS 8 необходимо добавить один или два специальных ключа в ваш файл Info.plist. Эти ключи содержат описания, которые будут отображаться пользователю в диалоговом окне запроса разрешения на доступ к местоположению.

Первый обязательный ключ - NSLocationWhenInUseUsageDescription. Этот ключ используется для приложений, которым требуется доступ к местоположению только тогда, когда приложение активно используется пользователем. Значением этого ключа должна быть строка, объясняющая, почему приложению нужен доступ к местоположению. Например: “Это приложение использует ваше местоположение для поиска ближайших магазинов”.

Для приложений, которым необходимо отслеживать местоположение пользователя даже в фоновом режиме, необходимо добавить второй ключ - NSLocationAlwaysUsageDescription. Значение этого ключа должно объяснять пользователю, почему приложению нужен постоянный доступ к местоположению. Например: “Приложению необходимо отслеживать ваше местоположение для отправления уведомлений о приближении к точкам интереса”.

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

Для удобства разработки можно добавить оба ключа в Info.plist, даже если приложение использует только один режим авторизации. Это обеспечит гибкость при будущих обновлениях функционала приложения.


Изменения в CLLocationManager для iOS 8

Помимо изменений в Info.plist, в iOS 8 были значительно изменены методы CLLocationManager, связанные с авторизацией. Теперь перед началом обновления местоположения необходимо явно вызвать один из методов запроса разрешения.

Для приложений, которым требуется доступ к местоположению только при активном использовании, следует вызывать метод requestWhenInUseAuthorization(). Этот метод покажет пользователю диалоговое окно с просьбой разрешить доступ к местоположению только тогда, когда приложение активно используется.

Для приложений, которым необходимо отслеживать местоположение в фоновом режиме, следует использовать метод requestAlwaysAuthorization(). Этот запрос покажет пользователю диалоговое окно с просьбой разрешить постоянный доступ к местоположению.

Ключевой момент - эти методы необходимо вызывать до вызова startUpdatingLocation() или startMonitoringSignificantLocationChanges(). Если вы попытаетесь начать обновление местополнения без предварительного запроса разрешения, CLLocationManager не вернет координаты.

Также важно отметить, что в iOS 8 изменились делегаты CLLocationManager. Теперь для обработки состояния авторизации используется свойство authorizationStatus, а не отдельные методы. Вы можете проверить текущий статус авторизации с помощью:

swift
let status = CLLocationManager.authorizationStatus()

Возможные значения статуса:

  • .notDetermined - пользователь еще не разрешил или запретил доступ
  • .restricted - доступ ограничен родительским контролем или корпоративной политикой
  • .denied - пользователь запретил доступ
  • .authorizedWhenInUse - пользователь разрешил доступ при активном использовании
  • .authorizedAlways - пользователь разрешил постоянный доступ

После вызова метода запроса авторизации, вы должны реализовать делегат locationManager(_:didChangeAuthorizationStatus:) для обработки ответа пользователя.


Решения для обратной совместимости с iOS 7

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

Для обеспечения совместимости с iOS 7 и iOS 8, вы можете использовать следующий подход:

  1. Проверьте версию iOS перед вызовом методов авторизации:
swift
if #available(iOS 8.0, *) {
 // Код для iOS 8 и новее
 locationManager.requestWhenInUseAuthorization()
} else {
 // Код для iOS 7 и старше
 // Нет необходимости вызывать методы авторизации
}
  1. Добавьте оба ключа в Info.plist - NSLocationWhenInUseUsageDescription и NSLocationAlwaysUsageDescription. Это обеспечит работу приложения на всех версиях iOS.

  2. Реализуйте проверку статуса авторизации перед началом обновления местоположения:

swift
func startLocationUpdates() {
 if CLLocationManager.locationServicesEnabled() {
 if #available(iOS 8.0, *) {
 let status = CLLocationManager.authorizationStatus()
 if status == .authorizedWhenInUse || status == .authorizedAlways {
 locationManager.startUpdatingLocation()
 }
 } else {
 // Для iOS 7 и старше
 locationManager.startUpdatingLocation()
 }
 }
}
  1. Реализуйте делегат для обработки изменения статуса авторизации:
swift
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
 if status == .authorizedWhenInUse || status == .authorizedAlways {
 locationManager.startUpdatingLocation()
 }
}
  1. Убедитесь, что экземпляр CLLocationManager объявлен как strong свойство, чтобы предотвратить его освобождение из памяти:
swift
private var locationManager: CLLocationManager!
  1. Для отладки в симуляторе XCode измените местоположение: Debug → Location → Apple (или другое значение).

Эти шаги обеспечат корректную работу вашего приложения как на iOS 7, так и на iOS 8 и более новых версиях.


Особенности iOS 11 и новее

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

В iOS 11 был введен новый ключ в Info.plist - NSLocationAlwaysAndWhenInUseUsageDescription. Этот ключ необходим для приложений, которые хотят использовать как фоновое, так и активное отслеживание местоположения. Хотя для базовой работы можно обойтись без этого ключа, его наличие рекомендуется для корректной работы всех функций.

Для приложений, использующих режим “всегда” (always), в iOS 11 появилась возможность уточнить тип использования фонового отслеживания. Вы можете добавить ключ NSLocationBackgroundLocationUpdateUsageDescription в Info.plist, чтобы предоставить дополнительное объяснение о том, почему вашему приложению необходимо фоновое отслеживание местоположения.

Также в iOS 11 изменился способ обработки запросов авторизации. Теперь система может кэшировать ответ пользователя, и повторные вызовы методов запроса авторизации могут не показывать диалоговое окно. Это означает, что ваше приложение должно быть готово к обработке как разрешенного, так и отклоненного статуса авторизации.

Для отладки в iOS 11 и новее рекомендуется использовать функцию “Simulate Location” в Xcode, которая позволяет эмулировать движения устройства с различными скоростями и типами траекторий.

Если ваше приложение работает неправильно на iOS 11 и новее, проверьте:

  1. Все ли необходимые ключи добавлены в Info.plist
  2. Правильно ли обрабатываются статусы авторизации
  3. Нет ли ошибок в реализации делегатов CLLocationManager
  4. Правильно ли используется фоновое обновление местополнения

Источники

  1. Stack Overflow - Location Services Not Working in iOS 8 — Подробное объяснение проблемы с CLLocationManager в iOS 8: https://stackoverflow.com/questions/24062509/location-services-not-working-in-ios-8
  2. Stack Overflow - CLLocation Manager Not Working iOS 8 — Решение проблемы с CLLocationManager, включая советы по симулятору Xcode: https://stackoverflow.com/questions/29390754/cllocation-manager-not-working-ios-8
  3. Stack Overflow - CLLocationManager Troubleshooting in iOS 8 — Пошаговое руководство по устранению проблем с CLLocationManager: https://stackoverflow.com/questions/26833695/cllocationmanager-troubleshooting-in-ios-8
  4. Nevan.net - Core Location Manager Changes in iOS 8 — Обзор изменений в CLLocationManager в iOS 8 от эксперта: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
  5. Mackuba.eu - Changes to Location Tracking in iOS 11 — Анализ изменений в отслеживании местоположения в iOS 11: https://mackuba.eu/2017/07/13/changes-to-location-tracking-in-ios-11/

Заключение

Проблемы с сервисами местоположения в iOS 8 возникают из-за фундаментальных изменений в механизме авторизации доступа к данным местоположения. Основная причина, по которой приложение не отображается в настройках и не возвращает координаты, заключается в том, что iOS 8 требует явного запроса разрешения через специальные методы CLLocationManager и наличие соответствующих ключей в Info.plist.

Для решения этой проблемы необходимо:

  1. Добавить ключи NSLocationWhenInUseUsageDescription и/или NSLocationAlwaysUsageDescription в Info.plist с описанием, почему приложению нужен доступ к местоположению
  2. Вывать методы requestWhenInUseAuthorization() или requestAlwaysAuthorization() перед началом обновления местоположения
  3. Реализовать делегат для обработки изменения статуса авторизации
  4. Обеспечить обратную совместимость с iOS 7 с помощью проверки версии операционной системы
  5. Для iOS 11 и новее добавить дополнительные ключи в Info.plist при необходимости

Следуя этим рекомендациям, вы сможете восстановить корректную работу сервисов местоположения в вашем приложении на iOS 8 и более новых версиях, сохранив при этом совместимость с iOS 7.

O

В iOS 8 SDK необходимо вызывать requestAlwaysAuthorization (для фонового местоположения) или requestWhenInUseAuthorization (только для местоположения при работе в активном состоянии) на CLLocationManager перед запуском обновлений местоположения. Также необходимо наличие ключа NSLocationAlwaysUsageDescription или NSLocationWhenInUseUsageDescription в Info.plist с сообщением, которое будет отображаться в запросе. Для обратной совместимости с iOS 7 проверяйте, запущен ли пользователь под iOS 8 или iOS 7.

L

В симуляторе Xcode необходимо изменить местоположение: Debug → Location → Apple (или другое). Также попробуйте использовать requestAlwaysAuthorization вместо requestWhenInUseAuthorization. Проблема может быть связана с изменениями в iOS 8, как описано в статье http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/.

H

Убедитесь, что ключи NSLocationWhenInUseUsageDescription и NSLocationAlwaysUsageDescription добавлены в Info.plist. Если приложение не отображается в Настройки → Конфиденциальность → Службы местоположения, это указывает на проблему с plist. Для отладки удалите локализованные значения и оставьте только глобальные. CLLocationManager должен быть объявлен как strong свойство для предотвращения освобождения памяти.

N

В iOS 8 Core Location больше не автоматически запрашивает разрешение. Чтобы получить координаты, в Info.plist нужно добавить ключ NSLocationWhenInUseUsageDescription (или NSLocationAlwaysUsageDescription) и в коде вызвать requestWhenInUseAuthorization (или requestAlwaysAuthorization) до startUpdatingLocation. После запроса пользователь увидит диалог «Разрешить доступ к местоположению…». Если пользователь отклоняет запрос, приложение не будет отображаться в разделе «Настройки» → «Службы местоположения».

K

В iOS 11 произошли значительные изменения в отслеживании местоположения. Для приложений, которые непрерывно отслеживают местоположение пользователя, потребуется время для внесения изменений. Для конфигурации авторизации “всегда” для служб местоположения выполните следующие действия: добавьте ключ NSLocationWhenInUseUsageDescription и ключ NSLocationAlwaysAndWhenInUseUsageDescription в ваш файл Info.plist.

Авторы
O
Разработчик
H
Разработчик
J
Разработчик
L
Разработчик
N
Разработчик/Блогер
K
Разработчик/Блогер
Проверено модерацией
Модерация