Чому трекер настрою — це більше, ніж CRUD?
Ви закладаєте модель даних — і вже на етапі аналітики розумієте: п'ятибальна шкала не дає потрібної деталізації, а емодзі перетворюють обчислення на хаос. Ми стикалися з цим у кожному другому проекті. Наш досвід показує: правильно спроектований Mood tracking додаток — це не стільки інтерфейс, скільки продумана система роботи з емоційними даними.
Що реально ускладнює задачу
Головна технічна складність — модель даних. Настрій можна оцінювати за п'ятибальною шкалою, за шкалою валентність-arousal, з емодзі, з тегами контексту. Якщо структуру закласти невірно, то через місяць користувач бачить невалідні графіки або взагалі не може порівняти минулий місяць з поточним.
Друга біль — нагадування. UNUserNotificationCenter на iOS дає тільки 64 pending-сповіщення. При індивідуальному розкладі на кожен день тижня цей ліміт згорає миттєво. Потрібно або генерувати сповіщення динамічно через BGAppRefreshTask, або використовувати повторювані тригери з локальною логікою. На Android WorkManager з PeriodicWorkRequest надійніше, але й там Doze Mode ріже доставку при агресивних налаштуваннях енергозбереження.
Третя історія — аналітика. Ковзне середнє за 7 днів, кореляція настрою з активністю з HealthKit (кроки, сон), кластеризація патернів по днях тижня. Все це рахується на клієнті — і якщо не кешувати результати агрегації, то кожен відкритий екран аналітики перечитує весь CoreData store з помітною затримкою.
Як ми будуємо додаток для трекінгу настрою під ключ
Архітектурно — MVVM з Combine (iOS) або ViewModel + StateFlow (Android). Локальне сховище: CoreData з NSPersistentCloudKitContainer для iCloud-синку або Room + DataStore для Android. Бекенд потрібен не завжди — багато проектів працюють повністю offline-first.
Для кросс-платформенної версії на Flutter використовуємо Isar як вбудовану БД замість SQLite: він швидший при складних індексованих запитах і добре лягає на реактивну модель через watchLazy. Riverpod керує станом, charts_flutter або fl_chart — візуалізація.
Конкретний кейс: додаток з трекером настрою + щоденником. Користувач вносить запис — ми зберігаємо MoodEntry з timestamp, числовою оцінкою, enum-тегами (work, sleep, exercise, social) та опціональним текстом. Раз на добу фонова задача перераховує агрегати за останні 30 днів і кладе їх в окрему таблицю MoodAggregate. Екран аналітики читає тільки агрегати — ніяких важких запитів до основного сховища.
Інтеграція з Apple HealthKit documentation — запитуємо HKQuantityTypeIdentifier.stepCount та sleepAnalysis за період, корелюємо з mood-даними через просту лінійну регресію на клієнті. Користувачі бачать: «у дні, коли ви робили 8000+ кроків, ваш настрій в середньому на 0.8 бала вище».
Що входить в роботу
| Компонент | Деталі |
|---|---|
| Модель даних | Нормалізовані enum'и настрою, теги контексту, часові мітки UTC |
| Локальне зберігання | CoreData / Room / Isar з авто-агрегацією |
| Нагадування | Динамічна генерація з урахуванням лімітів ОС |
| Аналітика | Ковзні середні, кореляція з HealthKit / Google Fit |
| Інтеграції | HealthKit, iCloud Sync, експорт у PDF |
| Публікація | Налаштування App Store Connect / Google Play Console, TestFlight |
Процес роботи
Аудит вимог → проектування моделі → прототип у Figma → розробка → тестування (XCTest / Espresso) → публікація. Ми гарантуємо дотримання App Store Review Guidelines та рекомендацій Google Play щодо використання Billing 6.
Орієнтири за термінами
| Етап | Термін (тижнів) |
|---|---|
| MVP (журнал + базова аналітика + нагадування) | 3–5 |
| Повноцінний додаток (HealthKit, синк, PDF, onboarding) | 8–12 |
Вартість розраховується індивідуально після аналізу вимог. Ціна помилки при самостійній розробці може сягати 50% бюджету. Зв'яжіться з нами — оцінимо ваш проект.
Які помилки найчастіше допускають при розробці?
Як ми кешуємо агрегати
Замість перерахунку при кожному відкритті аналітики ми запускаємо фонове завдання раз на добу і зберігаємо результат в окрему таблицю MoodAggregate.
- Зберігати mood-записи як рядки замість нормалізованих enum'ів — потім аналітика неможлива без міграції.
- Запускати агрегацію на main thread у
viewDidAppear— користувач бачить фріз при відкритті аналітики. - Ігнорувати часові пояси: якщо користувач перелетів в іншу країну, записи за «сьогодні» потрапляють у «вчора». Зберігати UTC, відображати в local timezone.
- Просити дозвіл на сповіщення при першому запуску без пояснення — відмова від дозволу обнуляє всю логіку нагадувань назавжди (повторно запросити не можна, тільки через Settings).
Замовте розробку трекера настрою — отримайте готове рішення з гарантією якості. Наш досвід: 5+ років у мобільній розробці, 30+ успішних проектів, сертифіковані інженери.







