persist stopwatches
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
class Stopwatch: ObservableObject, Identifiable {
|
||||
let id = UUID()
|
||||
class Stopwatch: ObservableObject, Identifiable, Codable {
|
||||
let id: UUID
|
||||
@Published var name: String
|
||||
@Published var elapsedTime: TimeInterval = 0
|
||||
@Published var isRunning: Bool = false
|
||||
@@ -18,10 +18,44 @@ class Stopwatch: ObservableObject, Identifiable {
|
||||
private var startTime: Date?
|
||||
private var accumulatedTime: TimeInterval = 0
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id, name, elapsedTime, isRunning, startTime, accumulatedTime
|
||||
}
|
||||
|
||||
init(name: String) {
|
||||
self.id = UUID()
|
||||
self.name = name
|
||||
}
|
||||
|
||||
required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try container.decode(UUID.self, forKey: .id)
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
elapsedTime = try container.decode(TimeInterval.self, forKey: .elapsedTime)
|
||||
isRunning = try container.decode(Bool.self, forKey: .isRunning)
|
||||
startTime = try container.decodeIfPresent(Date.self, forKey: .startTime)
|
||||
accumulatedTime = try container.decode(TimeInterval.self, forKey: .accumulatedTime)
|
||||
|
||||
if isRunning {
|
||||
// Restart the timer if it was running.
|
||||
// We also need to update current elapsedTime based on how much time passed since startTime
|
||||
if let start = startTime {
|
||||
elapsedTime = accumulatedTime + Date().timeIntervalSince(start)
|
||||
}
|
||||
startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(id, forKey: .id)
|
||||
try container.encode(name, forKey: .name)
|
||||
try container.encode(elapsedTime, forKey: .elapsedTime)
|
||||
try container.encode(isRunning, forKey: .isRunning)
|
||||
try container.encode(startTime, forKey: .startTime)
|
||||
try container.encode(accumulatedTime, forKey: .accumulatedTime)
|
||||
}
|
||||
|
||||
deinit {
|
||||
timer?.cancel()
|
||||
}
|
||||
@@ -31,8 +65,11 @@ class Stopwatch: ObservableObject, Identifiable {
|
||||
|
||||
startTime = Date()
|
||||
isRunning = true
|
||||
|
||||
timer = Timer.publish(every: 0.1, on: .main, in: .common)
|
||||
startTimer()
|
||||
}
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.publish(every: 0.01, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.sink { [weak self] _ in
|
||||
self?.tick()
|
||||
@@ -71,12 +108,12 @@ class Stopwatch: ObservableObject, Identifiable {
|
||||
let hours = Int(elapsedTime) / 3600
|
||||
let minutes = Int(elapsedTime) / 60 % 60
|
||||
let seconds = Int(elapsedTime) % 60
|
||||
let tenths = Int((elapsedTime.truncatingRemainder(dividingBy: 1)) * 10)
|
||||
let tenths = Int((elapsedTime.truncatingRemainder(dividingBy: 1)) * 100)
|
||||
|
||||
if hours > 0 {
|
||||
return String(format: "%02i:%02i:%02i.%01i", hours, minutes, seconds, tenths)
|
||||
return String(format: "%02i:%02i:%02i.%02i", hours, minutes, seconds, tenths)
|
||||
} else {
|
||||
return String(format: "%02i:%02i.%01i", minutes, seconds, tenths)
|
||||
return String(format: "%02i:%02i.%02i", minutes, seconds, tenths)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user