Документ фиксирует архитектуру и рабочие правила Firebase Analytics/Crashlytics в SwiftUI-WorkoutApp.
- Основная цель аналитики: техническая диагностика ошибок и сбоев.
- Аналитика используется как breadcrumbs-контекст для Crashlytics:
- какой экран был открыт перед сбоем;
- какие ключевые действия выполнял пользователь;
- какие ошибки приложения (
app_error) произошли в сценарии.
- Продуктовая персонализация на базе этих событий не является целью.
- Единая модель событий:
AnalyticsEventscreenView(screen: AppScreen, source: AppScreen? = nil)userAction(action: UserAction)appError(kind: AppErrorKind, error: Error)
- Провайдерная схема:
AnalyticsProvider(протокол)FirebaseAnalyticsProvider(отправка в Firebase)NoopAnalyticsProvider(тесты/превью/UITest-конфигурации)
AnalyticsServiceделает fan-out во все подключенные провайдеры.
AnalyticsServiceсоздается вSwiftUI_WorkoutAppApp.- Сервис прокидывается через
Environment(\.analyticsService) для экранов. - В
Viewиспользуется@Environment(\.analyticsService). - Для экранов используется
View.trackScreen(...). - Для частей вне
Environmentприменяется инъекция черезinit(analytics:). - Прямые вызовы Firebase SDK из экранов и ViewModel не используются.
- Открытие экранов логируется только через
.trackScreen(...). userActionлогируется только для реальных пользовательских действий (например,Buttonaction).- Логирование
userActionвыполняется в точке нажатия:- до
guard; - до сетевых вызовов;
- до ранних
return.
- до
- Навигационные переходы через
NavigationLinkотдельно какuserActionне логируются. - Для
appErrorотправляются:operation,error_domain,error_code. - Для non-fatal ошибок дополнительно вызывается
Crashlytics.crashlytics().record(error:).
- События ориентированы на диагностику и не должны содержать PII.
- Запрещено передавать:
user_id,username, email, телефон, текст сообщений/комментариев, координаты/адрес, URL аватаров, сырые поисковые запросы. - Для
select_*и фильтров допускаются только безопасные диагностические значения из контролируемых источников (enum, справочники, настройки). - Для
sourceиспользуется типизированныйAnalyticsEvent.AppScreen, без строковых литералов.
screenViewвнедрен на root/tab экранах и ключевых дочерних экранах.userActionвнедрен для основных CTA-кнопок в auth/profile/parks/events/messages/journals/settings.appErrorвнедрен в приоритетныхcatch-ветках:- auth/profile;
- parks/events;
- messages/journals.
- Для service/view-model слоя без
EnvironmentDI закрыт черезinit(analytics:)и единыйanalyticsServiceизSwiftUI_WorkoutAppApp.
- Базовая регрессия:
make formatmake test
- Crashlytics run script должен выполняться только в
Release(есть guard по$CONFIGURATIONв build phase). - Для финальной ручной валидации перед релизом используются Debug/Release проверки и выборочный просмотр событий в Firebase console.
- Каждый новый экран обязан иметь
.trackScreen(...). - Каждое новое критичное пользовательское действие обязано иметь
userAction. - Каждая новая критичная error-ветка обязана логировать
appError. - Имена событий остаются сценарными и диагностически полезными.
SwiftUI-WorkoutApp/Services/Analytics/AnalyticsEvent.swiftSwiftUI-WorkoutApp/Services/Analytics/AnalyticsService.swiftSwiftUI-WorkoutApp/Services/Analytics/FirebaseAnalyticsProvider.swiftSwiftUI-WorkoutApp/EnvironmentKeys/AnalyticsServiceEnvironmentKey.swiftSwiftUI-WorkoutApp/Extensions/View+Analytics.swiftSwiftUI-WorkoutApp/SwiftUI_WorkoutAppApp.swift