-
Notifications
You must be signed in to change notification settings - Fork 121
Description
This issue is discovered when testing #14438 and is affecting trunk too.
The trigger is:
- Have a test site that has a timezone completely different from the device timezone. In my case, test site is UTC-6 while device is UTC+7
- Start app, login to site freshly (can switch from another site to it),
- Switch to This Year in Performance card,
- Confirm that the data is shown correctly,
- Immediately rebuild app,
- Check Performance card again, confirm that the visitors and conversion data are not shown.
Expected: Performance card should be able to show the cached data that's downloaded on step 3-4.
The issue does not seem to appear when site and device timezone are the same, but I can't really tell how different the timezones should be to trigger the issue. So, this might be an edge case as I don't think we've heard report about it.
Investigation.
This is what I can investigate so far.
When logging in to a new site for the first time, as DashboardViewModel is being initialized, it also initializesself.storePerformanceViewModel.
StorePerformanceViewModel then initializes its siteTimezone: TimeZone = .siteTimezone, which calls this:
woocommerce-ios/WooCommerce/Classes/Extensions/TimeZone+Woo.swift
Lines 6 to 12 in e3571f9
| extension TimeZone { | |
| /// Returns the TimeZone using the timezone configured in the current website | |
| /// | |
| static var siteTimezone: TimeZone { | |
| #if !os(watchOS) | |
| return ServiceLocator.stores.sessionManager.defaultSite?.siteTimezone ?? .current |
In my test, defaultSite is still nil (perhaps because it's still early in the process), so StorePerformanceViewModel uses device timezone instead (UTC+7 in my case). The part that sets the predicate for fetching cached data then uses this timezone:
woocommerce-ios/WooCommerce/Classes/ViewRelated/Dashboard/StoreStats/StoreStatsPeriodViewModel.swift
Lines 106 to 113 in e3571f9
| let formattedDateString: String = { | |
| let date = timeRange.latestDate(currentDate: currentDate, siteTimezone: siteTimezone) | |
| return StatsStoreV4.buildDateString(from: date, timeRange: .today) | |
| }() | |
| let predicate = NSPredicate(format: "siteID = %ld AND period == %@ AND date == %@", | |
| siteID, | |
| timeRange.summaryStatsGranularity.rawValue, | |
| formattedDateString) |
The card then fetches and saves "Day" time range data by default. As we change the time range "This Year", the app then proceeds to fetch and save it, still using the device timezone. The data is saved with "2024-12-31" in its date value.
Now, on Step 5 after the app is rebuilt, defaultSite is now available. As StorePerformanceViewModel is recreated, it now uses the site's timezone (UTC-6 in my case). I can't figure out why yet, but this causes the formattedDateString in summaryStatsResultsController above to be off by one, "2025-01-01". As the saved data's value is "2024-12-31", the app now is unable to show the cached data.