简体   繁体   中英

Making NSTimer run in the background on a physical device

I have a timer app that I have made.

When I run it on the iPhone X on the simulator, the timer will run in the background just fine, but when I test it on my physical device (iPad Pro), it does not run in the background.

  • When I say in the background, I mean when you press the off button located on the top (iPad)/side (iPhone) of the device, so that the screen goes black.

Is this a glitch on the simulator's behalf, or something that I am not aware of, or is there something I need to change about my app to make it work in the background on PHYSICAL DEVICES as well?

Thanks

In DidBackground:

  1. stop normalTimer.
  2. start New backgroundTaskTimer

In WillForeground:

  1. stop backgroundTaskTimer.
  2. start normalTimer

Find below sample code:

In Appdelegate:

Declaration:

  var backgroundUpdateTask: UIBackgroundTaskIdentifier!

  var backgroundTaskTimer:Timer! = Timer()

Implementation:

func doBackgroundTask() {
    DispatchQueue.global(qos: .default).async {
        self.beginBackgroundTask()

        if self.backgroundTaskTimer != nil {
            self.backgroundTaskTimer.invalidate()
            self.backgroundTaskTimer = nil
        }

        //Making the app to run in background forever by calling the API
        self.backgroundTaskTimer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.startTracking), userInfo: nil, repeats: true)
        RunLoop.current.add(self.backgroundTaskTimer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        // End the background task.
        self.endBackgroundTask()

    }
}

func beginBackgroundTask() {
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(withName: "Track trip", expirationHandler: {
        self.endBackgroundTask()
    })
}

func endBackgroundTask() {
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

In ApplicationDidEnterBackground:

 func applicationDidEnterBackground(_ application: UIApplication) {

    //Start the background fetch
                self.doBackgroundTask()

        }

In ApplicationWillEnterForeground:

func applicationWillEnterForeground(_ application: UIApplication) {

    if self.backgroundTaskTimer != nil {
        self.backgroundTaskTimer.invalidate()
        self.backgroundTaskTimer = nil
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM