Due to the limitations of the mechanism, the time difference is mainly calculated by using the time before saving into the background and the saved time and the current time after coming out of the background, and the latest remaining time is obtained through the refresh function.
Current issues: In the simulator environment, the countdown of about 10 minutes was tested and it ran normally. However, after it was downloaded on real device, there would be a phenomenon where the countdown was accurate for the first minute. After more than 1 minute, the countdown was delayed, resulting in the failure to connect normally and the countdown had already started before entering the background. The time difference between the save times prevents the normal continuous countdown in the background.Please see the picture for the code. Please ask. How can I fix it?Thnaks!
issues code:
func updateTimer() {
if self.start {
if self.count > 0 {
self.count -= 1
} else {
switch currentPhase {
case .work:
currentPhase = .rest
pomodoros += 1
count = pomodoros == interval ? (longBreak * 60) : (shortBreak * 60)
countDiff = 0
isBreaked = true
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
case .rest:
if pomodoros == 4 {
pomodoros = 0
isBreaked = false
}
currentPhase = .work
count = 1500
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
}
self.start.toggle()
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
}
}
}
func fetchTime() {
if let saveDate = UserDefaults.standard.object(forKey: "saveTime") as? Date {
(self.countDiff) = getTimeDifference(startDate: saveDate)
self.refresh(seconds: self.countDiff)
} else {
removeSavedDate()
self.time.upstream.connect().cancel()
}
}
func saveTime() {
let shared = UserDefaults.standard
shared.set(Date(), forKey: "saveTime")
}
func refresh(seconds: Int) {
self.count -= seconds
self.time = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
}
.onReceive(vm.time) {(_) in
vm.updateTimer()
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) {_ in
print("willEnterForegroundNotification")
if vm.start {
vm.fetchTime()
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) {_ in
print("didEnterBackgroundNotification")
vm.start = true
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) {_ in
print("willResignActiveNotification")
if vm.start {
vm.saveTime()
}
}
I want to make the timer can continue to count in the background. Not affected by mobile phone system mechanisms.