1

I'd like to create a simple timer app that works the same way of the native timer of iOS. To start I just write some simple code that print the second starting to 0 to infinite. The first problem was that if you go to the home screen, the task obviously stops to work so I easily sorted just checking the box into background mode - Audio Airplay, and Picture in Picture (inside project - targets - Signing and Capabilities) now my task works fine.. even in the background.. unless you put your app into a real device in this case when you go into the background it doesn't work

after that I searched online for a solution and what I've learnt that Apple does't allow the apps to work into the background as you pleased and after 180 seconds the system just "kill" the background task. I just wonder how all the timer app in the Appstore works..

An Interesting thing that I've come across was when I watched an Apple developer conference that they talk about this new framework of background that you basically can make your app working in the background for heavy tasks when the iPhone is charging, and not only that you can forecast when the user will use your app and have some background tasks that work in the background in order to prepare the app to be updated. The link is this https://developer.apple.com/videos/play/wwdc2019/707/

after this I've tried different approaches to sort my problem but nothing has worked yet.. I have followed this tutorial which I found interesting https://medium.com/over-engineering/a-background-repeating-timer-in-swift-412cecfd2ef9 but it didn't work for me (maybe because of the version of swift outdated or simply because of me) if you guys have managed to make the timer work in the background in your real device let me know.. I would like to understand it well rather than copy and paste the code.

Happy coding to all

the tutorial code:

class RepeatingTimer {

    let timeInterval: TimeInterval

    init(timeInterval: TimeInterval) {
        self.timeInterval = timeInterval
    }

    private lazy var timer: DispatchSourceTimer = {
        let t = DispatchSource.makeTimerSource()
        t.schedule(deadline: .now() + self.timeInterval, repeating: self.timeInterval)
        t.setEventHandler(handler: { [weak self] in
            self?.eventHandler?()
        })
        return t
    }()

    var eventHandler: (() -> Void)?

    private enum State {
        case suspended
        case resumed
    }

    private var state: State = .suspended

    deinit {
        timer.setEventHandler {}
        timer.cancel()
        /*
         If the timer is suspended, calling cancel without resuming
         triggers a crash. This is documented here https://forums.developer.apple.com/thread/15902
         */
        resume()
        eventHandler = nil
    }

    func resume() {
        if state == .resumed {
            return
        }
        state = .resumed
        timer.resume()
    }

    func suspend() {
        if state == .suspended {
            return
        }
        state = .suspended
        timer.suspend()
    }
} 
Rich
  • 115
  • 1
  • 9
  • 1
    Take a look at [this answer](https://stackoverflow.com/a/50200606/1630618) – vacawama Feb 09 '20 at 12:59
  • You’ve linked to an article about a “background timer”, i.e. running a timer on a background _thread._ That WWDC video you reference is talking about an entirely different concept, letting your app run tasks while the app is not active, ie. in background _state._ But these are two completely different uses of the word “background” and shouldn’t be conflated. Bottom line, something like vacawama’s answer is sufficient here. But no GCD timers are needed (and, frankly, only suggest a confusion between two completely different concepts). You can use the standard `Timer` here. – Rob Feb 09 '20 at 19:39
  • And sorry to be the bearer of bad news, but the former 180 seconds we had to continue tasks has now been reduced to 30 seconds in iOS 13. – Rob Feb 09 '20 at 19:44
  • thanks Rob for your answer, I was guessing I could use that new framework somehow but as vacawama suggest I can simply add a local notification for my timer and I will not need to work on the background. Easy peasy. cheers – Rich Feb 10 '20 at 11:45

0 Answers0