Under the swiftUI framework, the timer cannot continue to count in the background

29 Views Asked by At

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.

0

There are 0 best solutions below