简体   繁体   中英

How to Make Timer Run in Background Xcode IOS

I have an issue with my app. I have a countdown timer that runs in the app. Initially before i made adjustments to the app delegate method: applicationDidEnterBackground , the timer would still run if i left the app.(Not closed the app, just in the home screen.)

I placed a notification trigger in applicationDidEnterBackground . This may have caused the timer to stop running.

I need to send a notification to the user to return to the app before the timer ends. (Hence the notification in applicationDidEnterBackground ) I want to give the user a certain time to return to the app before the timer stops.

Right now.... the notification is sent, but the timer ends immediately.

func applicationDidEnterBackground(_ application: UIApplication) {
    let content = UNMutableNotificationContent()
    //adding title, subtitle, body and badge
    content.title = "Hey if you will not come back"
    content.subtitle = "your timer will be killed"
    content.body = ""
    content.badge = 1
    //getting the notification trigger
    //it will be called after 5 seconds

    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

    //getting the notification request
    let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)


    //adding the notification to notification center
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

ViewController.swift

 @objc func countdown (){

    if valueToInt != 0 {
        valueToInt -= 1
        sliderLabel.text = String(valueToInt)
    } else {
        endTimer()
    }

    sliderLabel.text = timeFormatted(valueToInt)
}


func startTimer() {

    countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector (ViewController.countdown), userInfo: nil, repeats: true)

    countdown()

    stopOutlet.isHidden = false
    startOutlet.isHidden = true
    titlleLabel.isHidden = true
    sliderView.isHidden = true

 }

You can not run any code in background continuously unless you explicitly ask for it. To do any background task you have to activit Background Modes. Targets->Capabilities->Background Modes For the specific solution that you're looking you can ask system for some extra time in background without turning Background Modes on. Apple will give you're max time of 2min 59 seconds this is what I have tested but documentation only says under 3 minutes.

// Declare a background task by default I set it to TaskInvalid
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid

Before going to background mode initiate and begin the background task

backgroundTask = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
        self?.endBackgroundTask()
    })

// endBackgroundTask is a helper function which you will call once you're done with your task
private func endBackgroundTask() {
    UIApplication.shared.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

You can even call the endBackgroundTask function before you invalidate the timer

 @objc func countdown (){

if valueToInt != 0 {
    valueToInt -= 1
    sliderLabel.text = String(valueToInt)
} else {
    // call endBackgroundTask if you didn't call system will terminate it
    self.endBackgroundTask()
    endTimer()
}

   sliderLabel.text = timeFormatted(valueToInt)
}

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