Разработка мобильного приложения для мониторинга погоды
Погодные приложения — деceptively простая задача. Взять API, показать температуру и иконку. Но в продакшене появляются вопросы: какой провайдер данных точнее для конкретного региона, как сделать карту осадков которая не тормозит на слабых устройствах, как виджет на экране обновляется без постоянного drain батареи, и как уведомление о граде приходит за 10 минут а не постфактум.
Источники погодных данных
Выбор провайдера определяет точность, особенно вне крупных городов.
| Провайдер | Прогноз | Обновление | Особенности |
|---|---|---|---|
| Open-Meteo | 16 дней | 1ч | Бесплатно, open-source, хорошая Европа/СНГ |
| OpenWeatherMap | 8 дней | 3ч | Широкое покрытие, alertы |
| Tomorrow.io | 15 дней | 1ч | Minutecast, hyperlocal |
| Meteoblue | 7 дней | 3ч | Мезомасштабные модели, горы |
| Яндекс Погода API | 7 дней | 1ч | Точнее для РФ/СНГ |
Для максимальной точности — агрегация нескольких источников с весовым усреднением по историческим данным для конкретной точки. Для большинства проектов достаточно одного провайдера.
На мобиле погодные данные кэшируются локально — CoreData/Room для структурированных данных о погоде. TTL кэша: текущие условия — 10 минут, часовой прогноз — 1 час, 14-дневный — 6 часов.
Карта осадков
Самая нагрузочная часть. Тайловые карты осадков (radar tiles) — WMS или XYZ-тайлы, обновляемые каждые 5-10 минут.
На iOS: MapKit с MKTileOverlay — кастомный класс, который загружает тайлы по шаблону URL https://tiles.provider.com/radar/{z}/{x}/{y}/{timestamp}.png. Анимация — цикл по массиву timestamps с CADisplayLink или Timer для смены overlay'ев.
На Android: Mapbox или Google Maps с TileOverlay. Для анимации — меняем TileProvider источник на каждый фрейм с fade transition.
Проблема производительности: если загружать тайлы по одному на каждый фрейм анимации — мерцание. Правильно: preload все фреймы в background queue до старта анимации, хранить в памяти NSCache/LruCache, крутить анимацию по готовым. Лимит предзагрузки: 6-10 фреймов × 9 видимых тайлов = ~100 тайлов, около 5-10 МБ в памяти.
Виджет домашнего экрана
iOS: WidgetKit с TimelineProvider. Entry раз в 15-30 минут (система регулирует сама). Виджет не может выполнять сетевые запросы напрямую — TimelineProvider запрашивает данные в getTimeline(in:completion:), формирует массив TimelineEntry на несколько часов вперёд. TimelineReloadPolicy.atEnd — перезагрузка по истечении timeline.
SwiftUI-вью для виджета не поддерживает жесты кроме Link. Три размера: .systemSmall, .systemMedium, .systemLarge — для каждого своя вёрстка.
Android: Glance (Jetpack) — Compose-подобный API для App Widgets. Обновление через GlanceAppWidgetManager + WorkManager задача по расписанию.
Данные между основным приложением и виджетом: iOS — App Groups + UserDefaults(suiteName:). Android — SharedPreferences с провайдером.
Уведомления об опасных явлениях
Push-уведомления о граде, шторме, гололёде — через серверный scheduler. Каждые N минут проверяем weather alerts от провайдера для всех подписанных координат пользователей → если есть новый alert → FCM/APNs. Приоритет: high для критических явлений (APNs apns-priority: 10, FCM priority: high).
Для немедленных оповещений (торнадо, экстренные сигналы) — UNNotificationContent с interruptionLevel: .critical (iOS 15+): проходит через режим «Не беспокоить».
Геофенсинг для «мне важна погода в текущем месте»: CLLocationManager.startMonitoringSignificantLocationChanges() — уведомление при смещении на ~500м, без постоянного GPS-трекинга.
Сроки
Базовое погодное приложение (текущие условия, 7-дневный прогноз, виджет) — 2-4 недели. С картой осадков, уведомлениями об экстремальных явлениях и несколькими локациями — 6-8 недель. Стоимость рассчитывается индивидуально.







