Реалізація геозон (Geofencing) у мобільному додатку
Геозона — це не просто «повідомлення, коли користувач прийшов». За цією задачею ховається цілий пласт обмежень платформ, які виробники посилюють з кожною мажорною версією ОС. Додаток, який відмінно працював на iOS 15, на iOS 17 може мовчати — і це не баг у вашому коді.
Обмеження платформ, які важливо знати до початку розробки
iOS. CLLocationManager підтримує до 20 активних геозон одночасно — системний лімі, не наш. Радіус мінімум 100 метрів — менше не моніторяться. На пристроях без A12+ чіп точність ще нижча. CLCircularRegion доставляє події didEnterRegion / didExitRegion, але затримка може становити 3-5 хвилин залежно від режиму енергозбереження. В iOS 13+ потрібно запитувати Always авторизацію через двохшаговий діалог: спочатку whenInUse, потім користувач сам йде в Settings. Напрямо попросити Always вже не можна — Apple відклене при ревью.
Android. Geofencing API в com.google.android.gms:play-services-location вимагає Google Play Services. На Huawei без GMS — потрібен окремий шлях через HMS LocationKit. Android 10+ ввів ACCESS_BACKGROUND_LOCATION як окреме дозвіл, яке користувач видає в Settings, а не в стандартному діалозі. На Android 12 додали SCHEDULE_EXACT_ALARM для точних будильників — без нього Geofencing на Doze-пристроях може не спрацьовувати в потрібний момент. Деякі виробники (Xiaomi MIUI, Samsung One UI з агресивною економією батареї) вбивають фонові сервіси раніше, ніж API встигне доставити подію.
Як реалізуємо
iOS: базовий сценарій
let region = CLCircularRegion(
center: CLLocationCoordinate2D(latitude: 55.7558, longitude: 37.6173),
radius: 200,
identifier: "office_zone"
)
region.notifyOnEntry = true
region.notifyOnExit = false
locationManager.startMonitoring(for: region)
При перевищенні лімету 20 зон — пріоритизуємо за відстанню від поточної позиції і динамічно перегружаємо набір активних регіонів через stopMonitoring / startMonitoring. Логіка ротації — в locationManager(_:didUpdateLocations:).
Для проектів, де потрібно більше 20 зон або радіус менше 100 метрів — переходимо на Visit Monitoring (startMonitoringVisits()) або Significant Location Changes у комбінації з серверною перевіркою геозони за координатами.
Android: Geofencing API + WorkManager
val geofence = Geofence.Builder()
.setRequestId("warehouse_exit")
.setCircularRegion(lat, lon, 150f)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(30_000) // DWELL через 30 секунд
.build()
val request = GeofencingRequest.Builder()
.addGeofence(geofence)
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.build()
geofencingClient.addGeofences(request, geofencePendingIntent)
PendingIntent ведє на BroadcastReceiver, який запускає WorkManager-задачу замість прямого виконання логіки. Це важливо: прямий запуск довгої задачі з Receiver на Android 8+ вызивает BackgroundExecutionLimits виключення.
Для Huawei HMS — com.huawei.hms:location з практично ідентичним API, але окремою реєстрацією PendingIntent через GeofenceService.
Серверна валідація як страховка
Мобільне геозонування ненадійне саме по собі. Для критичних бізнес-сценаріїв (контроль виїзду транспорту, геймифікація з призами) будуємо додаткову серверну перевірку: пристрій періодично відправляє координати, сервер перевіряє перетин полігонів через PostGIS або геозони через Redis GEORADIUS. Мобільний Geofencing — швидкий тригер, сервер — фінальний арбітр.
Робота з дозволами правильно
Найчастіша причина відхилення в App Store — неправильне пояснення NSLocationAlwaysAndWhenInUseUsageDescription. Apple читає строки в Info.plist і вимагає конкретного опису: «для відправки повідомлення при вході в зону самовивозу» замість «для роботи додатку».
У Google Play з травня 2023 фонова геолокація проходить ручний ревью. Заявка повинна пояснювати конкретний юзкейс і показувати відео-демонстрацію. Закладайте на це 3-7 днів.
Процес роботи
Аналіз вимог: кількість зон, мінімальний радіус, платформи, наявність GMS у цільової аудиторії. Проектування архітектури з урахуванням обмежень платформ. Реалізація з коректним управлінням дозволами. Тестування: Walk Test через Xcode Simulator Location, реальні виїзди для Android. Підготовка описів для ревью.
Строк: три-шість днів залежно від кількості платформ, складності логіки тригерів і наявності серверної частини.







