raouaoul
raouaoul

Reputation: 882

Timer counting up in iOS Live Activity

I'm wondering if it's possible to create a simple seconds counter that is counting up in iOS Live Activities that would start from the provided unix timestamp and be relative to current date. For example: '00:01', '00:02', ...

I know how to create a countdown timer, like so:

Text(Date(timeIntervalSinceNow: 60), style: .timer)

But I haven't been successful in getting it to work the other way around, or finding much relevant information regarding this.

Upvotes: 3

Views: 3119

Answers (4)

Frederic Adda
Frederic Adda

Reputation: 6092

This is the Text initializer you are looking for:

Text(context.attributes.recordingStart, style: .timer)

I used it in the following implementation of a live activity:

  • In the Activity attributes I passed the recordingStart as a static attribute, since this does not change.
struct RecordingInProgressAttributes: ActivityAttributes {
   struct ContentState: Codable, Hashable {
        // Dynamic stateful properties about your activity go here!
    }

    // Fixed non-changing properties about your activity go here!
   let recordingStart: Date
}

Note that recordingStart is a Date here, not a timestamp.


  • in the live activity file, I created the body like so:
struct RecordingInProgressLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: RecordingInProgressAttributes.self) { context in
            Text(context.attributes.recordingStart, style: .timer)
        } dynamicIsland: { context in
           /// other stuff, like dynamic island
        }
    }
}

Upvotes: 0

jusynth
jusynth

Reputation: 191

If you want a timer that starts immediately after the live activity begins you can do this:

 Text(Date(timeIntervalSinceNow: Double(Date().timeIntervalSince(Date())) - Double(Date().timeIntervalSince(Date() - 1))
                        ),
                        style: .timer)

Upvotes: 0

raouaoul
raouaoul

Reputation: 882

This is the solution I ended up going with. I noticed that the timer will start counting up when the passed in time interval is negative value. [context.state.startedAt] is unix timestamp in seconds.

Text(
  Date(
    timeIntervalSinceNow: Double(context.state.startedAt) - Date().timeIntervalSince1970
  ),
  style: .timer
)

Upvotes: 2

Chandaboy
Chandaboy

Reputation: 1359

Please check this answer I hope it will solve your problem

//
//  SampleStopWatch.swift
//

import UIKit

class SampleStopWatch:UIViewController {
    
    var timer:Timer?
    var startTime = Date()
   
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
    }
    
    @objc func updateTimer() {
        let timeInterval =  Date().timeIntervalSince(startTime)
        let titleLabel = timeInterval.stringFromTimeInterval() // show this text on label
        //labeltoShow.text = titleLabel
        print("title label " + titleLabel)
    }
}
extension TimeInterval{
    
    func stringFromTimeInterval() -> String {
        
        let time = NSInteger(self)
        
        let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
        let seconds = time % 60
        let minutes = (time / 60) % 60
        let hours = (time / 3600)
        
        return String(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
        
    }
}

Upvotes: -3

Related Questions