What's the best way to detect when the app is entering the background for my view?

IosNstimer

Ios Problem Overview


I have a view controller that uses an NSTimer to execute some code.

What's the best way to detect when the app is going to the background so I can pause the timer?

Ios Solutions


Solution 1 - Ios

You can have any class interested in when the app goes into the background receive notifications. This is a good alternative to coupling these classes with the AppDelegate.

When initializing said classes:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];

Responding to the notifications

-(void)appWillResignActive:(NSNotification*)note
{
  
}
-(void)appWillTerminate:(NSNotification*)note
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];

}

Solution 2 - Ios

> In Swift 4.0

override func viewDidLoad() {
    super.viewDidLoad()
    
    let app = UIApplication.shared
   
    //Register for the applicationWillResignActive anywhere in your app.
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.applicationWillResignActive(notification:)), name: NSNotification.Name.UIApplicationWillResignActive, object: app)
}

@objc func applicationWillResignActive(notification: NSNotification) {

}

Solution 3 - Ios

On your applications AppDelegate the (void)applicationDidEnterBackground:(UIApplication *)application method will be called by iOS. You can stop your timer in there.

Solution 4 - Ios

For those looking to do this in Swift:

On init:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplicationWillResignActiveNotification, object: nil)

On deinit:

NSNotificationCenter.defaultCenter().removeObserver(self, name: UIApplicationWillResignActiveNotification, object: nil)

Responding to the notification:

dynamic private func applicationWillResignActive() {
	// Do things here
}

Apple encourages us to avoid dynamic dispatch and Objective-C selectors whenever possible in Swift, but this is still the most convenient way to do this.

Solution 5 - Ios

In swift 4.1:

I use the closure version:

var observer: NSObjectProtocol!

// inside init or viewDidLoad:
observer = NotificationCenter.default.addObserver(forName: .UIApplicationWillResignActive, object: nil, queue: nil) { _ in
    print("willResignActive")
}

deinit {
    NotificationCenter.default.removeObserver(observer)
}

The addObserver method returns an opaque object that needs to be removed at some point.

Solution 6 - Ios

only a side note: If you register a controller A to be notified going background, be careful that it will be called even if you (for example..) push a second controller B and You are displaying B: If this behaviour is not correct, is better to register/unregister in

didAppear/WillDisappear.

Solution 7 - Ios

- (void)applicationWillResignActive:(UIApplication *)application on your app delegate. You can also register for the UIApplicationWillResignActiveNotification notification on other objects.

You don't necessarily need to pause the timer, though. If you don't do anything, the app will get put to sleep anyway and won't execute any code. Presumably your timer will fire when you become active again (if you do). If you need to do something special there are 'did become active' delegate methods and notifications you can register for as well.

Solution 8 - Ios

Swift 4:

init() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(applicationWillResignActive),
                                           name: NSNotification.Name.UIApplicationWillResignActive,
                                           object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self,
                                              name: NSNotification.Name.UIApplicationWillResignActive,
                                              object: nil)
}

@objc private func applicationWillResignActive() {
    self.header.blur.effect = nil
}

Solution 9 - Ios

This is a better solution using closure

Declare observer

var backgroundObserver: NSObjectProtocol?

Initialize observer in viewDidLoad

backgroundObserver = NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: .main) { [weak self] notification in
  // Do what you want to do when app would go to background/ resign active  
}

Don't forget to remove observer in deinit

deinit {
    if let observer = backgroundObserver {
        NotificationCenter.default.removeObserver(observer)
    } 
}

Solution 10 - Ios

In Swift 5.1

    override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)

         NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
    
         NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        }
    
    override func viewWillDisappear(_ animated: Bool) { 
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)

        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }


@objc private func applicationWillResignActive() {
    }

    @objc private func applicationDidBecomeActive() {
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjfiskView Question on Stackoverflow
Solution 1 - IosJesse BlackView Answer on Stackoverflow
Solution 2 - IosAshok RView Answer on Stackoverflow
Solution 3 - IosDamienView Answer on Stackoverflow
Solution 4 - IosLukeView Answer on Stackoverflow
Solution 5 - IosjuanjoView Answer on Stackoverflow
Solution 6 - IosingcontiView Answer on Stackoverflow
Solution 7 - IossmparkesView Answer on Stackoverflow
Solution 8 - IosthexandeView Answer on Stackoverflow
Solution 9 - IosMohammad SadiqView Answer on Stackoverflow
Solution 10 - IosNaveen SharmaView Answer on Stackoverflow