I’m working on a simple timer, similar to the native iOs one in the Clock App.
In my app the user can tap a button to launch the liveActivity which shows up on the lock screen displaying the name of the timer, the time running down via the Text timerInterval initializer and a button to pause it relying on LiveActivityIntent.
struct MyWidgetsLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: MyWidgetsAttributes.self) { context in
// Lock screen/banner UI goes here
HStack {
Text(context.attributes.name)
.font(.title2)
.bold()
.multilineTextAlignment(.leading)
Text(timerInterval: context.state.startedAt...Date(timeInterval: context.state.remainingTime, since: .now), pauseTime: context.state.timerRuns == false ? Date(timeInterval: context.state.remainingTime, since: .now) : nil, countsDown: true)
.multilineTextAlignment(.trailing)
.font(.largeTitle)
Text(String(context.state.timerRuns))
Button (intent: PauseTimer(id: context.attributes.name)) {
Image(systemName: "pause.circle.fill")
}
.buttonBorderShape(.circle)
}
.padding()
.activityBackgroundTint(.white)
.activitySystemActionForegroundColor(Color.black)
} dynamicIsland: {....
However I can’t figure out a way to trigger an event once the countdown displayed in the Text-timerInterval hits zero, is there a way to do this?
Usually for an in-App-only timer I’d use the actual swift Timer and update a variable like remainingTime until that hits zero and read it to trigger the event like a sound in the code below, but I don’t know how to achieve the same using this Text-timerInterval.
Otherwise if this is impossible, should I rely on something like the below and feed it into the LiveActivity view having it update as each second goes by?
func startTimer() {
timer?.invalidate()
timer = nil
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) {_ in
if remainingTime > 0 {
remainingTime -= 0.1
timeProgress = remainingTime / TimeInterval(goal.totalSeconds)
goal.remainingTime = remainingTime
} else {
timer?.invalidate()
timer = nil
SoundManager.instance.stopSound()
SoundManager.instance.playSound(selectedSound: selectedSound.replacingOccurrences(of: " ", with: ""))
goal.remainingTime = TimeInterval(goal.totalSeconds)
do {
try modelContext.save()
} catch {
fatalError("Couldn't save your timer.")
}
}
}
}
1