Запрос разрешения на геолокацию
Корректно обрабатывайте разрешения и конфиденциальность.
«Запрос разрешения на геолокацию» — бесплатный урок Swift Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Зачем для доступа к местоположению требуется разрешение
На платформах Apple доступ к местоположению пользователя относится к операциям, связанным с конфиденциальностью. Ваше приложение должно явно запросить авторизацию, прежде чем Core Location начнёт передавать координаты. При первом запросе система показывает диалог разрешения.
- Пользователь предоставляет авторизацию отдельно для каждого приложения.
- Обойти её программно нельзя.
import CoreLocation
let manager = CLLocationManager()Ключи описания использования в Info.plist
Перед запросом авторизации необходимо добавить строку описания использования в Info.plist. Эти строки отображаются для пользователя в диалоге разрешения. Два основных ключа:
NSLocationWhenInUseUsageDescription— только для доступа на переднем плане.NSLocationAlwaysAndWhenInUseUsageDescription— также для доступа в фоновом режиме.
Отсутствие соответствующего ключа приводит к незаметному сбою запроса или аварийному завершению приложения.
<!-- Info.plist -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location to show nearby places.</string>Создание CLLocationManager
CLLocationManager — это основной объект, координирующий службы определения местоположения. Создайте один экземпляр, сохраните на него сильную ссылку и назначьте делегат для получения обратных вызовов.
final class LocationService: NSObject {
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
}
}Запрос авторизации при использовании приложения
Вызовите requestWhenInUseAuthorization(), чтобы запросить доступ на переднем плане. Система показывает диалог только один раз, после чего запоминает выбор пользователя. Если выбор уже сделан, вызов ничего не делает.
func requestPermission() {
manager.requestWhenInUseAuthorization()
}Запрос постоянной авторизации
Для обновлений в фоновом режиме (геозоны, непрерывное отслеживание) вызовите requestAlwaysAuthorization(). Apple требует сначала получить авторизацию при использовании приложения, а затем повысить её до постоянной. Используйте этот вариант только при необходимости и обоснуйте его в описании использования.
func requestAlways() {
manager.requestAlwaysAuthorization()
}Чтение состояния авторизации
Текущее состояние разрешения хранится в manager.authorizationStatus (это свойство экземпляра в iOS 14 и более новых версиях). Возможные значения включают .notDetermined, .denied, .restricted, .authorizedWhenInUse и .authorizedAlways.
let status = manager.authorizationStatus
switch status {
case .notDetermined: print("Ask the user")
case .denied, .restricted: print("No access")
case .authorizedWhenInUse, .authorizedAlways: print("Good to go")
@unknown default: break
}CLLocationManagerDelegate
Изменения авторизации доставляются асинхронно через делегат. Реализуйте locationManagerDidChangeAuthorization(_:), чтобы реагировать на выбор пользователя. Никогда не предполагайте, что разрешение предоставлено сразу после вызова запроса.
extension LocationService: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedWhenInUse, .authorizedAlways:
manager.startUpdatingLocation()
default:
print("Not authorized")
}
}
}Обработка отказа или ограничения доступа
Если пользователь отказал в доступе, повторно запросить его нельзя. Вместо этого обнаружьте состояние .denied и направьте пользователя в раздел Настройки. Состояние .restricted означает, что доступ заблокирован родительским контролем или профилем MDM; восстановить его из приложения также нельзя.
func handle(_ status: CLAuthorizationStatus) {
if status == .denied {
// Deep-link the user to Settings > Privacy > Location
print("Open Settings to enable location")
}
}Авторизация точности (точное или приблизительное местоположение)
Начиная с iOS 14 пользователь может предоставить только сниженную (приблизительную) точность. Проверьте manager.accuracyAuthorization. Если Вам действительно нужны точные данные (например, для пошаговой навигации), вызовите requestTemporaryFullAccuracyAuthorization(withPurposeKey:) с ключом, определённым в Info.plist.
if manager.accuracyAuthorization == .reducedAccuracy {
manager.requestTemporaryFullAccuracyAuthorization(
withPurposeKey: "PreciseForNavigation"
)
}Проверка включения служб определения местоположения
Помимо разрешения для отдельного приложения, на устройстве могут быть отключены службы определения местоположения. Проверьте CLLocationManager.locationServicesEnabled() в фоновой очереди (вызов в главном потоке может его заблокировать). Если службы отключены, ни одно приложение не получает данные о местоположении.
DispatchQueue.global().async {
if CLLocationManager.locationServicesEnabled() {
print("System location is on")
} else {
print("System location is off")
}
}Полный процесс авторизации
Объединим всё вместе: создайте менеджер, установите делегат, запросите авторизацию при использовании приложения, а затем запустите обновления внутри обратного вызова авторизации. Это канонический шаблон для любой функции, использующей местоположение.
final class LocationService: NSObject, CLLocationManagerDelegate {
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
}
func locationManagerDidChangeAuthorization(_ m: CLLocationManager) {
if m.authorizationStatus == .authorizedWhenInUse {
m.startUpdatingLocation()
}
}
}Быстрая проверка: авторизация
Проверьте, насколько хорошо Вы понимаете процесс авторизации.
Итоги: запрос авторизации
Вы узнали, как безопасно запрашивать разрешение на доступ к местоположению:
- Добавьте
NSLocationWhenInUseUsageDescription(и вариант для постоянного доступа, если он нужен) в Info.plist. - Создайте
CLLocationManager, сохраните на него сильную ссылку и установите его делегат. - Вызовите
requestWhenInUseAuthorization(), а затем повышайте авторизацию до постоянной только при необходимости. - Реагируйте в
locationManagerDidChangeAuthorization(_:)и обрабатывайте случаи отказа, ограничения и сниженной точности.
Часто задаваемые вопросы
Урок «Запрос разрешения на геолокацию» бесплатный?
Да — полный текст урока «Запрос разрешения на геолокацию» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Запрос разрешения на геолокацию»?
Корректно обрабатывайте разрешения и конфиденциальность. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Запрос разрешения на геолокацию»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Запрос разрешения на геолокацию
- Получение местоположения пользователя
- Отображение карт в SwiftUI
- Геокодирование и регионы