From eaf0c8f93be3e649f47aa9183e0bc690c40127cb Mon Sep 17 00:00:00 2001 From: alexandrev-tibco Date: Thu, 10 Sep 2026 06:34:21 +0200 Subject: [PATCH] Fix GA4: screen_view de Dashboard fuera de refreshData() (build 87) #44 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit logScreenView('Dashboard') estaba dentro de refreshData(), que se re-ejecuta con cada cambio de CoreData (incl. imports de iCloud, debounce 500ms) — 2 iPads con la app abierta generaban 1.400-2.100 views fantasma/día. Movido a DashboardView.onAppear (una vez por aparición), como el resto de pantallas. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01VXtwQP6nYnbLFVqsHiTK5G --- PortfolioJournal.xcodeproj/project.pbxproj | 20 +++++++++---------- .../ViewModels/DashboardViewModel.swift | 6 ++++-- .../Views/Dashboard/DashboardView.swift | 3 +++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/PortfolioJournal.xcodeproj/project.pbxproj b/PortfolioJournal.xcodeproj/project.pbxproj index 40428d3..0b9ab1d 100644 --- a/PortfolioJournal.xcodeproj/project.pbxproj +++ b/PortfolioJournal.xcodeproj/project.pbxproj @@ -541,7 +541,7 @@ CODE_SIGN_ENTITLEMENTS = PortfolioJournal/PortfolioJournalDebug.entitlements; ENABLE_USER_SCRIPT_SANDBOXING = NO; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_ASSET_PATHS = PortfolioJournal/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; ENABLE_PREVIEWS = YES; @@ -582,7 +582,7 @@ CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; PROVISIONING_PROFILE_SPECIFIER = "porfoliojournal"; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_ASSET_PATHS = PortfolioJournal/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; ENABLE_PREVIEWS = YES; @@ -739,7 +739,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = PortfolioJournalWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_ASSET_PATHS = PortfolioJournalWidget/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; @@ -774,7 +774,7 @@ CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; PROVISIONING_PROFILE_SPECIFIER = "Portfolio Journalwidget"; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_ASSET_PATHS = PortfolioJournalWidget/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; @@ -805,7 +805,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -829,7 +829,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -852,7 +852,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -875,7 +875,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -899,7 +899,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = PortfolioJournalQuickUpdateExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = PortfolioJournalQuickUpdate/Info.plist; @@ -927,7 +927,7 @@ CODE_SIGN_ENTITLEMENTS = PortfolioJournalQuickUpdateExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 86; + CURRENT_PROJECT_VERSION = 87; DEVELOPMENT_TEAM = 2825Q76T7H; PROVISIONING_PROFILE_SPECIFIER = "PortfolioJournal QuickUpdate AppStore"; GENERATE_INFOPLIST_FILE = NO; diff --git a/PortfolioJournal/ViewModels/DashboardViewModel.swift b/PortfolioJournal/ViewModels/DashboardViewModel.swift index 582d3d4..31e0ed7 100644 --- a/PortfolioJournal/ViewModels/DashboardViewModel.swift +++ b/PortfolioJournal/ViewModels/DashboardViewModel.swift @@ -219,8 +219,10 @@ class DashboardViewModel: ObservableObject { // Detect internal data gaps (missing months between known snapshots) dataGaps = SnapshotGapDetector.detectGaps(sources: sources, snapshots: allSnapshots) - // Log screen view - FirebaseService.shared.logScreenView(screenName: "Dashboard") + // NOTE: no screen_view logging here — refreshData() fires on every + // relevant Core Data change (incl. iCloud imports), so logging from it + // inflated GA4 with thousands of phantom Dashboard views from devices + // left open. The view logs once per appearance in DashboardView.onAppear. } private func filteredSources() -> [InvestmentSource] { diff --git a/PortfolioJournal/Views/Dashboard/DashboardView.swift b/PortfolioJournal/Views/Dashboard/DashboardView.swift index 85f0dae..be21d03 100644 --- a/PortfolioJournal/Views/Dashboard/DashboardView.swift +++ b/PortfolioJournal/Views/Dashboard/DashboardView.swift @@ -112,6 +112,9 @@ struct DashboardView: View { goalsViewModel.selectedAccount = accountStore.selectedAccount goalsViewModel.showAllAccounts = accountStore.showAllAccounts goalsViewModel.refresh() + // Screen view logged here (once per appearance) — NOT inside + // refreshData(), which re-runs on every Core Data change. + FirebaseService.shared.logScreenView(screenName: "Dashboard") } // Performance: Combine account selection changes into a single handler .onChange(of: accountStore.selectedAccount) { _, newAccount in