Розробка мобільного додатку для польових сотрудників (Field Service)
Польовий технік приїхав до клієнта, відкрив додаток — а там білий екран, бо немає мобільного сигналу. Заявка на ремонт, історія обладнання, чеклист обстеження — все зависло. Саме тут ламаються більшість Field Service-додатків: вони будуються як звичайний CRUD поверх REST API і не передбачають офлайн-режим як першорядний сценарій.
Ключові технічні проблеми
Offline-first синхронізація. Польові сотрудники працюють на складах, у підвалах, в промислових зонах — покриття нестабільне. Потрібна двостороння sync-черга: дії користувача зберігаються локально (SQLite через Room або CoreData), потім синхронізуються при появі мережі. Конфлікт версій — найболючіша точка. Якщо два техніки одночасно закрили одну заявку офлайн, потрібна merge-стратегія. Зазвичай застосовуємо "last-write-wins" з логом операцій або CRDTs для деяких типів даних (наприклад, коментарі — append-only).
Фотографії та медіа. Акт виконаних робіт вимагає фото "до" і "після". На Android WorkManager з Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED) — стандартний спосіб відкладеного завантаження. Але нюанс: WorkManager не гарантує порядок виконання завдань при batch upload. Якщо порядок фото критичний — нумеруємо в імені файлу і приймаємо це на сервері.
Підпис на екрані. Canvas API (Android View.onDraw з Path, iOS UIBezierPath через CAShapeLayer) для захоплення підпису клієнта — завдання проста, поки не потрібен високоякісний експорт в PDF. Використовуємо iText (Android) або PDFKit (iOS) для генерації акта прямо на пристрої.
Карти та маршрутизація
Диспетчер бачить всіх польових сотрудників на карті в реальному часі — це WebSocket або MQTT від брокера (mosquitto / EMQX) до мобільного клієнта. Координати відправляємо батчами кожні 30 секунд через FusedLocationProviderClient (Android) або CLLocationManager з desiredAccuracy: kCLLocationAccuracyNearestTenMeters (iOS) — не кожну секунду, щоб не вбити батарею.
Оптимальний маршрут між 10–15 заявками за день — це задача Travelling Salesman, яку на мобільному клієнті не вирішують. Оптимізацію считає сервер (Google OR-Tools, Vroom), мобільний додаток лише відображає готовий маршрут через Google Maps SDK або MapKit з покроковою навігацією через deep link в Maps/Google Maps.
Стек та архітектура
Для Field Service-додатків з одним кодом під iOS та Android вибираємо Flutter або React Native з Expo. Flutter переважніший, коли є вимоги до кастомних віджетів (кастомна форма обстеження обладнання, drag-and-drop для позицій у заявці). React Native — якщо команда клієнта буде підтримувати код самостійно і у них JavaScript-бекграунд.
Архітектура: MVVM + Repository pattern. Локальна БД — SQLite (sqflite для Flutter, Room для Android-нативки). Sync-шар — окремий сервіс, який не змішується з бізнес-логікою.
З практики
Додаток для обслуговування торгових автоматів: ~200 техніків, кожен з 8–15 точками в день. Головна помилка в першій версії — синхронізація запускалась при кожній дії користувача через прямий HTTP-запит. При поганій мережі це приводило до того, що технік чекав 30 секунд після кожного закриття позиції. Переписали на чергу операцій (SQLite-таблиця pending_operations + WorkManager) — технік працює миттєво, синхронізація іде фоном. Кількість скарг на "додаток гальмує" впала до нуля.
Етапи
- Аудит існуючої системи (ERP, CRM, диспетчерський модуль) — розбираємось, з чим будемо синхронізуватися
- Проектування офлайн-моделі даних і стратегії розв'язання конфліктів
- Дизайн інтерфейсу з урахуванням використання в рукавицях і на яскравому сонці (контрастність, великі кнопки)
- Розробка і поетапна інтеграція з backend
- Пілот з групою техніків (10–20 осіб) до повного rollout
- Публікація в App Store і Google Play з MDM-профілем для корпоративних пристроїв
Строки від 6 тижнів (простий додаток з заявками та чек-листами) до 4–6 місяців для повнофункціональної платформи з диспетчерським модулем, маршрутизацією та інтеграцією з ERP. Вартість розраховується індивідуально після аналізу вимог.







