0

Here is code which I execute in background when user close the app, but it is weird behavior , after endBackgroundUpdateTask() method is executed , DispatchQueue still doesn't stops...

I steel continuos get notification.

What am I doing wrong?

you can try to take this snipped of code and try for yourself, it is really weird

var backgroundUpdateTask: UIBackgroundTaskIdentifier!

func beginBackgroundUpdateTask() {
    print("beginBackgroundUpdateTask")
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

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

func doBackgroundTask() {
    print("Strart")
    DispatchQueue.global().async {
        self.beginBackgroundUpdateTask()

        // Do something with the result.
        let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(AppDelegate.displayAlert), userInfo: nil, repeats: true)
        RunLoop.current.add(timer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        // End the background task.
        self.endBackgroundUpdateTask()
    }

    print("Finish")
}

func displayAlert() {
    print("displayAlert")
    let note = UILocalNotification()
    note.alertBody = "As a test I'm hoping this will run in the background every X number of seconds..."
    note.soundName = UILocalNotificationDefaultSoundName
    UIApplication.shared.scheduleLocalNotification(note)
}

func applicationDidEnterBackground(_ application: UIApplication) {
    log.debug("applicationDidEnterBackground")
    self.doBackgroundTask()

}

edit

var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var timerr: Timer?

func beginBackgroundUpdateTask() {
        appDeligate.log.debug("beginBackgroundUpdateTask")
        self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    appDeligate.log.debug("endBackgroundUpdateTask")
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
    timerr = nil
}

func doBackgroundTask() {
    print("Strart")
    DispatchQueue.global().async {
        self.beginBackgroundUpdateTask()

        // Do something with the result.
        self.timerr = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(TestViewController.displayAlert), userInfo: nil, repeats: true)
        RunLoop.current.add(self.timerr!, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        // End the background task.
        self.endBackgroundUpdateTask()
    }

    print("Finish")
}

func displayAlert() {
    print("displayAlert")
    let note = UILocalNotification()
    note.alertBody = "As a test I'm hoping this will run in the background every X number of seconds..."
    note.soundName = UILocalNotificationDefaultSoundName
    UIApplication.shared.scheduleLocalNotification(note)
}
Sirop4ik
  • 4,543
  • 2
  • 54
  • 121
  • 1
    You never invalidate the timer, so it keeps firing. Nothing to do with "background tasks". – matt Feb 05 '17 at 12:32
  • @matt I added edited code in question, did you say about that? If yes, it is steel doesn't work( or you mean something another? – Sirop4ik Feb 05 '17 at 20:19
  • I don't see what difference your edit makes. I repeat, the whole "background tasks" thing is irrelevant here. Once a repeating timer is started, it just keeps going (in the Simulator) until you call `invalidate()` on it. You never do, so it just keeps going. – matt Feb 05 '17 at 20:23
  • @matt Thanks! I got your idea. I posted answer. I was confused because I thought if I was stopping `backgroundUpdate()` all tasks inside had to invalidate and purge automatically, but no – Sirop4ik Feb 06 '17 at 10:08

1 Answers1

0

Really issue was with Timer, I was needed put this line

timerr?.invalidate()

here

func endBackgroundUpdateTask() {
    appDeligate.log.debug("endBackgroundUpdateTask")
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
    timerr?.invalidate()
}

But anyway it is little bit weird , because I thought if I was stopping backgroundUpdate() all tasks inside had to invalidate and purge automatically, but no.

Thanks @matt

Sirop4ik
  • 4,543
  • 2
  • 54
  • 121