Table of Contents

Введение в напоминания на основе местоположения в iOS

Напоминания на основе местоположения превращают стандартное мобильное приложение в контекстно-ориентированного помощника, который предоставляет своевременные уведомления именно тогда, когда пользователь входит или покидает определенную географическую область. От напоминания пользователю, чтобы забрать рецепт, когда рядом с аптекой, до уведомления их о том, чтобы установить домашнюю тревогу при выходе из дома, эта функция повышает ежедневную производительность и вовлеченность. В iOS комбинация структуры Базовое местоположение и UserNotifications обеспечивает надежную и конфиденциальную основу для реализации такой функциональности. Эта статья предоставляет всеобъемлющее, готовое к производству руководство по созданию напоминаний на основе местоположения, охватывающее все, от разрешений и конфигурации геозоны до продвинутых оптимизацией и стратегиями тестирования.

Понимание основного местоположения и уведомлений пользователей

Двумя основными фреймворками iOS являются Core Location и UserNotifications. Core Location обрабатывает все географические отслеживания, включая мониторинг региона (геозонды), службы определения местоположения с существенным изменением и стандартные обновления местоположения GPS. UserNotifications управляет планированием, представлением и управлением локальными и удаленными уведомлениями. Для напоминаний на основе местоположения мы используем локальные уведомления, потому что они полностью запускаются на устройстве, не требуют подключения к сети и уважают конфиденциальность пользователя.

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

Устанавливать разрешения

Запросить разрешение на местоположение

Прежде чем начать мониторинг местоположения, ваше приложение должно получить явное разрешение пользователя. iOS отображает системную подсказку, которая включает целевую строку из вашего . Для мониторинга фоновой области вам нужно (iOS 11+) или . Код должен сначала позвонить в экземпляре :

let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()

Apple призывает разработчиков отложить запрос разрешения до тех пор, пока пользователь не получит контекст. Do not request always-authorization on first launch; вместо этого объясните преимущество перед показом подсказки. Также обработайте случай, когда пользователь изначально отказывает в разрешении, направив их в приложение «Настройки».

Запрос разрешения на уведомление

Одновременно вы должны запросить разрешение на отображение уведомлений. Это делается через :

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
 // Handle response
}

Если пользователь отказывает в разрешении на уведомление, рассмотрите возможность предоставления альтернативы (например, оповещения в приложении) или объяснения того, как уведомления улучшают опыт. Оба разрешения независимы - пользователь может разрешить местоположение, но отключить уведомления или наоборот.

Конфигурирование геозон и мониторинг регионов

Определение круглой области

Геозонд реализуется с помощью . Вы предоставляете координату центра (широта и долгота) и радиус в метрах. Минимальный радиус, который надежно поддерживает iOS, составляет около 100 метров, хотя тестирование на устройствах с хорошим GPS может дать меньшие радиусы. Укажите, хотите ли вы быть уведомлены о входе, выходе или обоих:

let center = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let region = CLCircularRegion(center: center, radius: 150, identifier: "OfficeRegion")
region.notifyOnEntry = true
region.notifyOnExit = true
locationManager.startMonitoring(for: region)

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

Мониторинг нескольких регионов

Часто у вас будет много напоминаний (например, созданные пользователем геозоны). Идентификаторы регионов в локальной базе данных (основные данные, сфера или пользовательские по умолчанию). При запуске приложения перерегистрируйте все активные регионы. Также удалите любые регионы, которые больше не нужны для пребывания в пределах 20 регионов.

// Remove regions when no longer needed
locationManager.stopMonitoring(for: region)

Мониторинг делегированного метода для выявления случаев, когда мониторинг региона не поддерживается (например, на старых устройствах) или ограничен настройками системы.

Обработка событий региона

Когда устройство пересекает границу геозоны, Core Location вызывает один из двух методов делегата: или . Ваша реализация должна проверить идентификатор региона, а затем запланировать локальное уведомление. Пример:

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
 guard region.identifier == "OfficeRegion" else { return }
 scheduleNotification(title: "Welcome to Office", body: "Don't forget to scan your badge.")
}

Обратите внимание, что эти методы делегирования называются, даже если ваше приложение приостановлено; iOS будет будить ваше приложение в фоновом режиме кратко. У вас есть около 30 секунд, чтобы выполнить код, прежде чем система снова приостанавливает вас. Используйте это время, чтобы запланировать уведомление (или обработать другую логику) как можно быстрее.

Восстановление штата после перезапуска приложения

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

Отправка локальных уведомлений

Создание контента уведомления

Используйте , чтобы определить название, корпус, звук и пользовательские данные:

let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = "You're near the store! Don't forget to buy groceries."
content.sound = .default
content.userInfo = ["regionID": "StoreRegion"]

Вы также можете включить , чтобы включить пользовательские действия (например, «Snooze» или «Mark as Done»).

Триггер и запрос

Поскольку мы хотим, чтобы уведомление было выпущено сразу после события в регионе, мы используем триггер с интервалом времени с очень короткой задержкой (1 секунда).

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
 if let error = error {
 // Log error (e.g., notification not added)
 }
}

Использование уникального идентификатора каждый раз предотвращает перезапись предыдущих уведомлений.Если вы хотите заменить ожидающее уведомление (например, обновить сообщение), используйте тот же идентификатор.

Настройка звука и значка

Вы можете предоставить пользовательский звуковой файл в своем пакете (должен быть менее 30 секунд) путем настройки . Номера значков устанавливаются через (или приращение на основе UIApplication.shared.applicationIconBadgeNumber). Помните, что значок очищается только тогда, когда пользователь открывает приложение или вы вручную его сбрасываете.

Обработка ошибок и соображения батареи

Обычные ошибки

Мониторинг региона может быть неудачным по нескольким причинам:

  • Не поддерживается на устройстве — некоторые старые iPad или iPod touch не имеют чипа сотовой связи / GPS..
  • Освобождение от работы — может быть ложным.
  • В Коране сказано: «Отрицание [[ФлТ:1]] — [[ФлТ:26]] является [[ФлТ:27]] или [[ФлТ:28]]».
  • Превышение предела области — если вы попытаетесь контролировать более 20 регионов, потерпит неудачу.

Внедрить делегат , чтобы зарегистрировать ошибку и сообщить пользователю изящно (например, «Невозможно контролировать это местоположение»).

Оптимизация батареи

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

  • Мониторинг только столько регионов, сколько необходимо (держитесь до 20 лет).
  • Используйте большие радиусы, когда точность не является критической (например, 500 м против 50 м).
  • Отключите мониторинг региона, когда приложение войдет в фон для несвязанных задач (использовать в соответствующих обратных вызовах жизненного цикла).
  • Для некритических напоминаний рассмотрите возможность использования службы определения местоположения с существенным изменением местоположения , которая предоставляет обновления только тогда, когда устройство перемещается значительно (500 м или более) и потребляет меньше энергии.

Тестирование напоминаний на основе местоположения

Моделирование местоположения в Xcode

Симулятор Xcode позволяет имитировать изменения местоположения. Используйте функцию «Имитация местоположения» (Debug > Simulate Location) и выберите файл GPX или привод на автостраде. Также можно вручную задать координаты с помощью кнопки «Расположение» в панели отладки. Однако обратите внимание, что мониторинг фоновой области не работает в симуляторе для всех сценариев; рекомендуется тестировать на физическом устройстве.

Тесты на блоки для региональной логики

Изолировать методы делегата и планирование уведомлений в тестируемые компоненты. Перемешайте и с использованием протоколов. Пример:

protocol RegionHandler {
 func didEnterRegion(with identifier: String)
}
class MockNotificationCenter: UNUserNotificationCenter {
 var addedRequest: UNNotificationRequest?
 override func add(_ request: UNNotificationRequest, withCompletionHandler: (Error?) -> Void) {
 addedRequest = request
 }
}

Тест, который вводит область, производит правильное название уведомления и тело, и что ошибки обрабатываются.

Реальный контрольный список тестирования

  • Тестирование событий входа и выхода, когда приложение находится на переднем плане, фоне и завершено.
  • Убедитесь, что несколько перекрывающихся регионов вызывают независимые уведомления.
  • Проверьте разрядку батареи в течение нескольких часов мониторинга.
  • Тест с отключенными службами определения местоположения, отключенным Wi-Fi и отключенными данными сотовой связи.
  • Убедитесь, что запросы уведомлений не повторяются, если пользователь повторно входит в один и тот же регион в течение короткого времени - реализуйте период «охлаждения» с использованием меток времени UserDefaults.

Конфиденциальность и пользовательский опыт лучшие практики

Прозрачность и согласие

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

Позволяет пользователям управлять напоминаниями

Предложите пользовательский интерфейс, где пользователи могут просматривать все активные напоминания, видеть геозону на карте и удалять напоминания по отдельности. Также пусть они временно приостанавливают все напоминания (например, во время отпуска). Удаление напоминания должно немедленно вызвать .

Обратная связь и пустые государства

Когда напоминания не установлены, покажите четкое пустое состояние с призывом к действию («Нажмите +, чтобы добавить напоминание о местоположении»). Если разрешения отклоняются, отобразите сообщение, объясняющее, что пользователь отсутствует, и кнопку, ссылающуюся на Настройки.

Не беспокоить и критические сигналы

Уведомления на основе местоположения не должны быть навязчивыми. Уважайте текущий режим фокусировки пользователя (не беспокоить) - система автоматически подавляет уведомления при включении. Не запрашивайте разрешение «критического оповещения», если напоминание действительно срочное (например, лекарство) и одобрено Apple.

Расширенные усовершенствования

iBeacon-Based Triggers

Для точности внутри помещений рассмотрите возможность использования диапазона iBeacon (] вместо геозон. Маяки обеспечивают точность до нескольких метров. Настройка аналогична: определяют область маяка по UUID, основным и второстепенным значениям, затем отслеживают вход / выход, а также диапазон для близости. Мониторинг iBeacon не требует всегда авторизации (когда использования достаточно), но воздействие батареи сопоставимо.

Сочетая значительное изменение местоположения

Обновления местоположения с существенным изменением запускаются изменениями вышки сотовой связи примерно каждые 500 метров. Вы можете использовать их для обновления списка близлежащих геозон, даже когда устройство движется быстро (например, в автомобиле). Однако события входа / выхода затем вычисляются по вашей собственной логике, а не по специальному мониторингу области системы. Это полезно, если вам нужно контролировать сотни областей - вы можете сохранить подмножество в памяти на основе текущей области пользователя.

Использование фоновых задач для предварительной находки

Если ваши напоминания требуют сетевых данных (например, часов работы магазина), вы можете запланировать (введенный в iOS 13) для обновления данных оппортунистически. Но будьте осторожны, чтобы не комбинировать его с событиями местоположения, чтобы избежать появления отслеживания пользователя в фоновом режиме для целей, не связанных с местоположением.

Обработка многочисленных уведомлений из одного и того же региона

Если пользователь задерживается на границе области, он может получить повторные события входа / выхода. Внедрить таймер охлаждения (например, «Не запускайте другое уведомление для этой области в течение не менее 5 минут»). Сохраните последнюю временную метку триггера в UserDefaults на идентификатор региона.

Заключение

Внедрение напоминаний на основе местоположения в iOS является мощным способом предоставления контекстно-ориентированных впечатлений. Объединив мониторинг региона Core Location с уведомлениями пользователей, вы можете создать функции, которые чувствуют себя интуитивно понятными и полезными. Ключ к успеху заключается в уважении конфиденциальности пользователей, оптимизации использования батареи, изящной обработке ошибок и обеспечении чистого интерфейса для управления напоминаниями. По мере того, как iOS продолжает развиваться, новые возможности, такие как (iOS 17+) еще больше упрощают фоновый мониторинг. Создайте свою реализацию на основе, описанной здесь, и вы предоставите готовую к производству, надежную систему напоминаний на основе местоположения.

Для дальнейшего чтения, обратитесь к официальной документации Apple: