Реализация поиска припаркованного автомобиля через мобильное приложение
Пользователь запарковался в торговом центре, вышел через час — и не помнит, где машина. Это простая задача, которая решается сохранением GPS-координаты в момент парковки. Но наивная реализация даёт погрешность 10–20 метров внутри паркинга или в плотной городской застройке — и пользователь всё равно бродит.
Как корректно определить момент парковки
Самый надёжный триггер — отключение от Bluetooth автомобиля. Когда пользователь глушит машину и уходит, телефон теряет Bluetooth-соединение с автомобилем (CarPlay, Android Auto или просто аудиосистема). Это событие — чёткий сигнал «машина запаркована здесь».
На iOS: CoreBluetooth + CBCentralManagerDelegate.centralManager(_:didDisconnectPeripheral:error:). При разрыве — сохраняем последнюю известную координату из CLLocationManager. Проблема: фиксируется разрыв по конкретному CBPeripheral.identifier, который нужно заранее связать с автомобилем пользователя.
На Android: BluetoothAdapter.ACTION_ACL_DISCONNECTED broadcast + фильтрация по имени/адресу устройства. Работает в background через BroadcastReceiver.
Альтернатива — алгоритм на основе активности: Google Activity Recognition API (DetectedActivity) определяет, когда пользователь переходит из IN_VEHICLE в ON_FOOT. В этот момент — сохраняем координату. Не требует Bluetooth, но срабатывает с задержкой ~30–60 секунд.
На iOS аналог: CMMotionActivityManager — определяет смену режима активности через акселерометр/барометр.
Сохранение и отображение метки
Координата сохраняется локально — UserDefaults/SharedPreferences для простого случая, или Core Data/Room если нужна история парковок. Метка на карте — кастомный MKAnnotationView / Marker с иконкой автомобиля.
Точность GPS в городе ухудшается от отражений (urban canyon effect). Усредняем 3–5 последних точек перед сохранением вместо одной — снижает случайные выбросы. CLLocation.horizontalAccuracy > 50 метров — не сохраняем, ждём лучшей точности.
Внутри многоуровневого паркинга GPS часто не работает вообще. В этом случае фиксируем последнюю точку перед въездом в подземный паркинг (GPS ещё работал) + номер этажа/уровня введённый вручную.
Навигация к машине
Направление и расстояние до сохранённой точки — компас с CLHeading (iOS) или SensorManager.SENSOR_DELAY_UI + TYPE_ROTATION_VECTOR (Android). Стрелка поворачивается по мере движения пользователя.
Для навигации «открыть в картах» — deep link в Google Maps / Apple Maps с координатами парковки как destination. Пешеходный маршрут строится в нативном приложении карт, не в нашем.
AR-режим поиска — наложение стрелки через камеру с расстоянием. ARKit (iOS) или ARCore (Android). Выглядит эффектно, практически полезно в сложных паркингах. Добавляет 3–4 дня разработки поверх базовой реализации.
История парковок и заметки
Если нужна история («где я парковался у этого офиса обычно») — Core Data / Room с таблицей parked_locations: координата, адрес (reverse geocoding через CLGeocoder / Geocoder), timestamp, опциональная заметка пользователя («3й этаж, секция B»).
Список последних мест — TableView / RecyclerView с ячейками: адрес, дата, миниатюра карты через MKMapSnapshotter (iOS) или статическая карта Google Maps Static API (Android). Тап по записи — открывает маршрут к этому месту. Полезно для повторяющихся поездок.
Лимит хранения — последние 20–50 мест, старые удаляются автоматически. Облачная синхронизация (iCloud через NSUbiquitousKeyValueStore или Firebase Firestore) — если пользователь меняет устройства.
Сроки
Базовая реализация (сохранение по Bluetooth-событию + отображение на карте + компас): 4–8 часов. С AR-режимом, историей парковок и умным определением через Activity Recognition: 1–2 рабочих дня. Стоимость рассчитывается индивидуально.







