Разработка мобильного приложения для городского транспорта (расписание, оплата)
Приложение городского транспорта работает в условиях постоянно меняющихся данных: расписания меняются по праздникам и сезонам, маршруты редактируются, транспорт опаздывает. Статичная база расписаний устаревает через неделю. Реальное время прибытия интересует пользователя больше, чем теоретическое расписание.
GTFS и реальное время
Стандарт обмена данными о расписании — GTFS (General Transit Feed Specification). Большинство городских транспортных систем публикуют GTFS-фиды: набор CSV-файлов с маршрутами, остановками, временами. Для реального времени — GTFS-RT (Realtime): Protobuf-потоки с TripUpdate, VehiclePosition, ServiceAlert.
На клиенте: парсинг Protobuf через protobuf-kotlin / Swift SwiftProtobuf. GTFS-RT обновляется каждые 15-30 секунд — polling или Server-Sent Events. VehiclePosition feed даёт координаты транспортных средств для отображения на карте.
Если городской оператор не предоставляет GTFS-RT — можно реализовать предсказание прибытия на основе статического расписания + исторических данных об опозданиях. Хуже, чем реальное время, но лучше, чем ничего.
Офлайн-расписание и кеширование
Пользователь в метро без интернета — расписание должно быть доступно. Стратегия: при первом запуске скачать полный GTFS bundle (~5-20 MB для среднего города), сохранить в SQLite через Room (Android) / GRDB (iOS). Запросы к расписанию — SQL по локальной БД, без сети.
Обновление в фоне: WorkManager (Android) с NetworkConstraint проверяет версию GTFS-фида раз в сутки, при обновлении — скачивает дельту или полный фид. BGAppRefreshTask (iOS) для аналогичного обновления.
Кеш реального времени: VehiclePosition и TripUpdate данные живут не более 60 секунд, хранить в памяти (не SQLite), очищать при устаревании.
Построение маршрута с пересадками
Маршрут от остановки А до остановки Б с возможными пересадками — задача для transit routing engine. Варианты:
Google Maps Directions API с mode=transit — самое простое решение. Возвращает маршрут с пересадками, временами, именами линий. Но: платно, нет доступа к raw данным, зависимость от Google.
OpenTripPlanner — open source transit router, работает с GTFS. Разворачивается на собственном сервере, клиент делает запросы к нему. Полный контроль над данными, бесплатно для своего сервера.
Raptor algorithm — быстрый алгоритм transit routing, можно реализовать серверно на Kotlin/Java. Для небольшого города (до 200 маршрутов) работает за миллисекунды.
На клиенте: отображение маршрута с пересадками — timeline view с цветовой кодировкой линий, время на каждом участке, иконки транспорта.
Оплата проезда
Оплата в приложении — QR-код или NFC.
QR-вариант: после оплаты генерируется QR с токеном (JWT или случайная строка), проверяется на терминале в транспорте. Токен однократного использования, живёт 30-60 минут.
NFC: Host Card Emulation (HCE) на Android — эмуляция бесконтактной карты, HostApduService. iOS до 17 не поддерживала сторонние NFC-платежи, с iOS 17.4 ограниченно доступно в ЕС. Для большинства кейсов — QR-код надёжнее.
Apple Pay / Google Pay как метод пополнения баланса в приложении — да, это работает везде. Сам проход через турникет — HCE или QR.
Транспортная карта в приложении: баланс, история пополнений, история поездок. Пополнение через карту, Apple Pay, Google Pay. Push-уведомление при низком балансе.
Карта с остановками и транспортом
Кластеризация остановок при низком zoom, разворачивание при приближении. Tap по остановке — ближайшие отправления в реальном времени: pull из GTFS-RT TripUpdate feed.
Маркеры транспортных средств в реальном времени из VehiclePosition. Анимация движения — интерполяция позиций (интервал обновления 15-30 сек, плавное перемещение за это время). Иконка маршрута на маркере: номер линии, цвет соответствующий GTFS routes.txt.
Стек
Android: Kotlin, Jetpack Compose, Room, WorkManager, Google Maps SDK или Mapbox. iOS: Swift, SwiftUI, GRDB, BackgroundTasks, MapKit или Mapbox. Кроссплатформа: Flutter с нативными модулями для NFC и background tasks.
Этапы: интеграция GTFS-источника → offline БД → transit routing → real-time → оплата → тестирование на реальных маршрутах города → публикация.
Срок: от 12 до 22 недель. Стоимость рассчитывается индивидуально.







