platinum
platinum

Reputation: 23

How to keep the timer running after the view/app is closed?

I know theres a lot of question related to mine, but I just cant figure out what to do in my situation.

Its an "open chest" type of game. It has a timer that once it reaches zero the user can continue to the next ViewController (This is ThirdViewcontroller, and the next is FourthViewController)

I also have the "back" button that allows you to go to the FirstViewController where you can continue doing other game related stuff, but from there you can also come to this SecondViewController to check the time remaining.

But every time I do that, the timer resets, how can I keep it running? While the user goes and to the other game related stuff? And how can I keep it running even after the app is closed?

The seconds remaining depends on the variables sent from the SecondViewController

Heres what I have done so far

class StudioWaitingViewController: UIViewController {

   var gameTimer = Timer()
   var studioTime = StudioTime()

   var secondsPassed : Double = 0 
   var timeNeededToRecord : Double = 0 
   var currentTime : Double = 0 
   var percentageOfBar = 0
   var countdown = 0 

override func viewDidLoad() {
       super.viewDidLoad()

       seeResultsButton.isHidden = true
       firstArtistWaitBar.transform = firstArtistWaitBar.transform.scaledBy(x: 1, y: 20)
       firstArtistWaitBar.progress = 0
       firstArtistWaitHour.text = String(format:"%.f", "\(timeNeededToRecord)s")


      gameTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateFirstArtist), userInfo: nil, repeats: true)

       countdown = Int(timeNeededToRecord)


   }

@objc func updateFirstArtist() {

       // if todo
       if secondsPassed < timeNeededToRecord {

           currentTime = secondsPassed / timeNeededToRecord
           secondsPassed += 1
           percentageOfBar = Int(currentTime * 100)
           firstArtistWaitPercentage.text = "\(percentageOfBar)%"


           firstArtistWaitHour.text = "\(countdown)s"
           countdown -= 1



           print(countdown)

           DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
               self.firstArtistWaitBar.setProgress( Float(self.currentTime) , animated: false)
               // 10-second animation changing from 100% to 0%
               UIView.animate(withDuration: 1.5, delay: 0, options: [], animations: { [unowned self] in
                   self.firstArtistWaitBar.layoutIfNeeded()
               })                                                 }



       } else if secondsPassed == timeNeededToRecord {

           firstArtistWaitPercentage.text = "Done!"
           firstArtistWaitBar.setProgress(1, animated: false)
           gameTimer.invalidate()

           firstArtistWaitHour.text = "Done!"

           UIView.animate(withDuration: 1.5, delay: 0, options: [], animations: { [unowned self] in
               self.firstArtistWaitBar.layoutIfNeeded()
           })

           seeResultsButton.isHidden = false
           gameTimer.invalidate()
       }
       // if todo
   }

Anyway, I'm still very new in coding, if you see anyway I can improve my code, please say

Upvotes: 0

Views: 672

Answers (1)

paulRick
paulRick

Reputation: 604

To enable a Timer func to run in the background you can mark the Audio, AirPlay, and Picture in Picture option on Background Modes on your Signing & Capabilities on your App's target.

Now, this is only valid when the app is on the background (not closed), it is not possible to perform any task when your app are closed. A workaround would be to store the date/time of when your app was last opened and do the proper calculations.

This can clarify more about background execution.

Upvotes: 1

Related Questions