1

I'm working on a timer-based app, and trying to build a widget that displays several timers at once.

It should look something like this

So, in order to accommodate multiple time items, my TimelineEntry contains an array of [SingleTimeItem]

struct MultipleTimeItemsEntry: TimelineEntry {
    
    let date: Date
    let timeItems: [SingleTimeItem]
    
    let configuration: MultipleConfigurationIntent
}

Next is my method for constructing the timeline. It's a bit incomprehensible, for which I'm sorry and tried to negate that with comments.

    var timeItems = configure(results: results, configuration: configuration)
    
    var entries = [MultipleTimeItemsEntry]()
        
    
    // Append initial entry
    entries.append(MultipleTimeItemsEntry(date: date, timeItems: tempTimeItems, configuration: configuration))
    
    
    // Sort by the time they should finish to construct a proper timeline of entries
    timeItems.sort {
        $0.timeFinished < $1.timeFinished
    }
    
    
    // Start mapping entries to their respective dates
    for i in 0...timeItems.count-1 {
        
        var tempTimeItems = timeItems
        
        // Mark all timers that should have finished before or simultaniously with timeItem[i] as finished
        for j in 0...i {
            if tempTimeItems[j].isRunning {
                tempTimeItems[j].isFinished = true
            }
        }
        
        // Return the array to its initial sorting
        
        tempTimeItems.sort {
            $0.timeStarted > $1.timeStarted
        }
        
        
        // Append entry for each timer finish (each entry containing finishes for all preceding timers)
        entries.append(MultipleTimeItemsEntry(date: timeItems[i].timeFinished, timeItems: tempTimeItems, configuration: configuration))
    }

    
    
    return entries

In addition to that, here's the entirety of my getTimeline method:

func getTimeline(for configuration: MultipleConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    
    var entries: [MultipleTimeItemsEntry] = []
    
    let currentDate = Date()
    
    entries.append(contentsOf: fetchTimeItemWithConfig(date: currentDate, configuration: configuration))
    
    print("Debug output")
    print(Date())
    print(entries[0].date)
    print(entries[0].timeItems[0].isFinished)
    print(entries[1].date)
    print(entries[1].timeItems[0].isFinished)
    
    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
}

For simplicity, I've added only one timer to present this.

When a timer is started, the Debug output is this:

enter image description here

It consists of 2 entries: one when the timer is started, and the other when it should finish and the UI should update, and they are 30 seconds apart.

Now to the punchline: for some reason, and I don't understand this AT ALL, the update doesn't happen.

Any ideas fellas?

pawello2222
  • 46,897
  • 22
  • 145
  • 209
Alexey Primechaev
  • 907
  • 1
  • 6
  • 13
  • Same problem no idea how to fix - tried everything – Hekes Pekes Feb 18 '21 at 16:25
  • Does this answer your question? [How to refresh multiple timers in widget iOS14?](https://stackoverflow.com/questions/65670736/how-to-refresh-multiple-timers-in-widget-ios14) – pawello2222 Feb 18 '21 at 23:05
  • @pawello2222 sadly, no. I chose an approach that is very similar to the one you suggested in the answer you provided. However, it doesn't work for me and I cannot see as to why. – Alexey Primechaev Feb 19 '21 at 10:02
  • @AlexeyPrimechaev Timers that are *30 seconds apart* may not work properly - did you try with longer intervals (like 5 mins)? – pawello2222 Feb 19 '21 at 10:20

0 Answers0