Реалізація геозон (Geofencing) у мобільному додатку
Додаток з геозонами на iOS 17 перестає доставляти сповіщення — і це не баг у вашому коді. Apple переписала логіку фонового моніторингу місцезнаходження, посилила вимоги до опису дозволів і додала нові ліміти. На Android схожа картина: Doze-режим, агресивні батарейні оптимізації вендорів та окремий дозвіл для фонової геолокації з ручним рев'ю в Google Play. Розробники, які ігнорують ці нюанси, отримують мовчазний додаток і погані відгуки.
Ми інтегруємо геозони з урахуванням усіх платформних обмежень. Досвід 10+ років і 50+ проєктів з геозонами дозволяють гарантувати стабільну роботу на останніх версіях ОС.
Обмеження платформ: таблиця порівняння
| Платформа | Макс. зон | Мін. радіус | Фонові обмеження | Робота без GMS |
|---|---|---|---|---|
| iOS | 20 | 100 м | Затримка 3-5 хв, iOS 13+ Always вимагає двоетапного запиту | Так (лише iOS) |
| Android | 100 (рекомендуємо не більше 50) | ~100 м для стабільності | Doze, battery saver, ACCESS_BACKGROUND_LOCATION з ручним рев'ю | Потрібен HMS на Huawei |
| Huawei HMS | 100 | 100 м | Аналогічно Android, але без Doze (EMUI свій режим) | Так (HMS) |
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 з агресивним battery saver) вбивають фонові сервіси раніше, ніж 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 днів.
Що входить в роботу
- Код інтеграції Geofencing API для iOS (Swift 5.9+, SwiftUI/UIKit) та Android (Kotlin, Jetpack Compose).
- Обробка лімітів і ротація зон.
- Коректне управління дозволами з текстом для App Store/Google Play.
- Тестування Walk Test на iOS та реальні виїзди на Android.
- Документація з архітектури та опис для рев'ю.
- Підтримка після запуску: доопрацювання, моніторинг, виправлення багів.
Процес роботи
Аналіз вимог: кількість зон, мінімальний радіус, платформи, наявність GMS у цільової аудиторії. Проектування архітектури з урахуванням обмежень платформ. Реалізація з коректним управлінням дозволами. Тестування: Walk Test через Xcode Simulator Location, реальні виїзди для Android. Підготовка описів для рев'ю.
Термін: від 3 до 6 днів залежно від кількості платформ і складності тригерів. Оцінимо ваш проєкт за 1 день — пишіть для консультації. Замовте реалізацію геозон під ключ з гарантією коректної роботи на останніх версіях ОС.







