13

My ViewController.swift

func startTimer() {
    timer = NSTimer().scheduleTimerWithTimerInvterval(1.0,target: self,selctor: Selector("couting"),userinfo: nil, repeats: true)
}

func pauseTimer() {
    timer.invalidate()
    println("pausing timer")
}

and this is appDelegate.swift

func applicateWillResignActive(application: UIApplication) {
    viewController().pauseTimer()
    println("closing app")
}

It is printing pausing timer and closing app but when I open again I see it never paused. How do I do it correctly?

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
user528432
  • 411
  • 2
  • 5
  • 18

5 Answers5

29

You have to set an observer listening to when the application did enter background. Add the below line in your ViewController's viewDidLoad() method.

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("myObserverMethod:"), name:UIApplicationDidEnterBackgroundNotification, object: nil)

Add the below function to receive the notification.

func myObserverMethod(notification : NSNotification) {
    println("Observer method called")

    //You may call your action method here, when the application did enter background.
    //ie., self.pauseTimer() in your case.
}

Happy Coding !!!

Suresh Kumar Durairaj
  • 2,104
  • 16
  • 24
  • this is perfect Suresh, and i have to create a new observer when user comes back so i can resume the timer? – user528432 Dec 30 '14 at 09:59
  • Yes, you have to create another observer listening to UIApplicationDidBecomeActiveNotification and similarly you call the actions inside the observer as specified above. – Suresh Kumar Durairaj Dec 30 '14 at 10:03
  • Awesome! i created same func when user enters again then resume timer. its working nicely (y) – user528432 Dec 30 '14 at 10:05
  • 1
    Please note that the syntax would be ```NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlayViewController.myObserverMethod(_:)), name:UIApplicationDidEnterBackgroundNotification, object: nil) ``` now (swift 2.3) – jrmgx Aug 13 '16 at 19:08
  • Perfect Solution! – Tom Coomer May 28 '17 at 15:30
  • I search this for 2 days, I set ```NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name:UIApplication.didBecomeActiveNotification, object: nil)``` in ```viewDidLoad```, when I enters app again, the timer is keep updating in previous paused time but no progress. Mean time, audio is continue to play. And I get this error when enter background ```Can't end BackgroundTask: no background task exists with identifier 21 (0x15), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.```. With Xcode 11 and iOS 13. – Zhou Haibo Oct 25 '19 at 12:42
  • You may have to extend the app's background execution time if you're doing any background task like the following. https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/extending_your_app_s_background_execution_time#overview – Suresh Kumar Durairaj Oct 27 '19 at 09:06
  • In my case I want to perform didEnterBackground for particular ViewController and this code works for whole application. – Poornima Mishra Dec 14 '21 at 10:15
7

Updated Answer for Swift 5:

NotificationCenter.default.addObserver
              (self,
               selector: #selector(myObserverMethod),
               name:UIApplication.didEnterBackgroundNotification, object: nil)

@objc func myObserverMethod() {
    print("Write Your Code Here")
}
Kerberos
  • 4,036
  • 3
  • 36
  • 55
Yunus Karakaya
  • 531
  • 3
  • 16
3

Accepted answer by @Suresh in Swift 3

Set an observer listening to when the application did enter background in your ViewController's viewDidLoad() method.

 NotificationCenter.default.addObserver(self, selector: #selector(myObserverMethod), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)

Add the below function to receive the notification.

 func myObserverMethod(notification : NSNotification) {

   print("Observer method called")

  //You may call your action method here, when the application did enter background.
  //ie., self.pauseTimer() in your case.

}
Brian Bird
  • 1,176
  • 18
  • 21
1

Updated Answer for Swift 4:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(myObserverMethod), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
}

@objc func myObserverMethod() {
    // Call your action method here, when the application did enter background.
}
Kunal Gupta
  • 2,984
  • 31
  • 34
YungGoat
  • 123
  • 1
  • 9
  • Don't forget `super viewDidLoad()` – Ashley Mills Aug 17 '18 at 10:01
  • 1
    improvement Swift 4: NotificationCenter.default.addObserver(self, selector: #selector(stopTimersMethod), name:UIApplication.didEnterBackgroundNotification, object: nil) – Heki Oct 30 '18 at 16:20
0

You are creating a new object and calling pauseTimer() on it:

viewController().pauseTimer()   // This line causes issue viewController(), creates a new instance

Instead of creating new object, either you should pass that instance to AppDelegate and call pauseTimer() on existing object or Listen for UIApplicationDidEnterBackgroundNotification notification in your view controller class and pause timer from there.

Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • tried but it only does is "println("pausing timer")" and doesn't stop the timer – user528432 Dec 29 '14 at 10:46
  • @djay: how did you passed the object ? Please read my answer once again – Midhun MP Dec 29 '14 at 10:51
  • whats the correct code for **ApplicationWillEnterBackground** in swift? – user528432 Dec 29 '14 at 10:59
  • @djay: if you are looking for notifications, check https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/#//apple_ref/c/data/UIApplicationDidEnterBackgroundNotification – Midhun MP Dec 29 '14 at 11:02
  • You can create your timer in AppDelegate class and use it in your viewcontroller ... by this you can easily set your timer invalidate when application is in background . – Prashant Vashisht Dec 29 '14 at 11:11