I have a Home Screen widget that contains a timer counting down to a specific date. In this image you can see the date calculations:
- eventDate: 25th Dec 2023 at 09:00:00
- entryDate(Date.now): This is just showing you the date in the first
SimpleEntry
for the widget. - getTimeRemaining(entryDate): This shows the number of seconds from the entryDate to the eventDate, figures out how many days there are ("43 days"), and how many hours:mins:secs to the event time, so "10:48:52".
- Then there's a second entry, entryDate2, that's one hour later, and the values are appropriately calculated.
When I create the timeline entries, I add them for:
- Now (1 entry)
- Now plus one hour to a week away (one entry per hour = 167 entries)
- Event date (1 entry)
- Event date plus one hour to a week later (one entry per hour = 167 entries)
Each SimpleEntry
entry contains a dictionary with the relevant timer details, and that's what the widget uses to determine what to display in the timer.
SwiftUI lacks any useful formatting for a timer. Even the developer docs state: "Example output: 36:59:01". Who wants to see a timer with 36 hours on it? I want it to say "1 day 12:59:01", so I munge the numbers about and grab the separate parts, converting 36:59:01 into "1 day" and "12:59:01". You can see that in the image above.
When the entry date of the timeline is reached and the widget is redrawn, it uses the entry containing the dictionary saying it should display "43 days" and the countdown timer should be 10:48:52, then an hour later the dictionary says it's 43 days 9:48:52, etc.
The issue is that the widgets, even though they're supposed to have entries at each hour, will always end up displaying something like "29:17:09". The timeline has an entry at every hour, so it should be using the right values. I've checked, and the right values are in the dictionary, so why does the timer keep getting out of sync?
I could cut out a massive amount of my widget code if only Text.init(date, style: .timer)
would allow some proper formatting.