iosswiftswiftuinsdateformatter

Live update relative time in SwiftUI


In my SwiftUI app, I'm showing relative time as follows.

struct ContentView: View {

    let date: Double = 1589014112

    var body: some View {
        Text(Date(timeIntervalSince1970: date).relativeTime())
    }
}

extension Date {
    func relativeTime(in locale: Locale = .current) -> String {
        let formatter = RelativeDateTimeFormatter()
        formatter.unitsStyle = .full
        return formatter.localizedString(for: self, relativeTo: Date())
    }
}

I get the time interval since 1970 as double from an API. I want to show relative time in my app. The output is as below.

enter image description here

The view updates only when I reload and it stays at "10 seconds ago" with every passing second. How to update it in real time? I want to change whenever the current date (Date()) changes.


Solution

  • You can use a TimerPublisher to trigger something periodically.
    Here is a quick example below;

    struct PlaygroundView: View {
    
        let timer = Timer.publish(
            every: 1, // second
            on: .main,
            in: .common
        ).autoconnect()
    
        let date = Date()
    
        @State var secondStr: String = ""
    
        var body: some View {
            Text(secondStr)
                .onReceive(timer) { (_) in
                    self.secondStr = self.date.relativeTime()
                }
        }
    }
    
    extension Date {
        func relativeTime(in locale: Locale = .current) -> String {
            let formatter = RelativeDateTimeFormatter()
            formatter.unitsStyle = .full
            return formatter.localizedString(for: self, relativeTo: Date())
        }
    }
    

    You can observe that the secondStr changes every second like
    1 seconds ago
    2 seconds ago
    and so on..