Handling applicationDidBecomeActive - "How can a view controller respond to the app becoming Active?"

IosIphoneIos4MultitaskingUiapplicationdelegate

Ios Problem Overview


I have the UIApplicationDelegate protocol in my main AppDelegate.m class, with the applicationDidBecomeActive method defined.

I want to call a method when the application returns from the background, but the method is in another view controller. How can I check which view controller is currently showing in the applicationDidBecomeActive method and then make a call to a method within that controller?

Ios Solutions


Solution 1 - Ios

Any class in your application can become an "observer" for different notifications in the application. When you create (or load) your view controller, you'll want to register it as an observer for the UIApplicationDidBecomeActiveNotification and specify which method that you want to call when that notification gets sent to your application.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(someMethod:)
                                             name:UIApplicationDidBecomeActiveNotification object:nil];

Don't forget to clean up after yourself! Remember to remove yourself as the observer when your view is going away:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification
                                              object:nil];

More information about the Notification Center.

Solution 2 - Ios

Swift 3, 4 Equivalent:

adding observer

NotificationCenter.default.addObserver(self,
    selector: #selector(applicationDidBecomeActive),
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

removing observer

NotificationCenter.default.removeObserver(self,
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

callback

@objc func applicationDidBecomeActive() {
    // handle event
}

Solution 3 - Ios

Swift 2 Equivalent:

let notificationCenter = NSNotificationCenter.defaultCenter()

// Add observer:
notificationCenter.addObserver(self,
  selector:Selector("applicationWillResignActiveNotification"),
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove observer:
notificationCenter.removeObserver(self,
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove all observer for all notifications:
notificationCenter.removeObserver(self)

// Callback:
func applicationWillResignActiveNotification() {
  // Handle application will resign notification event.
}
  

Solution 4 - Ios

Swift 5

fileprivate  func addObservers() {
      NotificationCenter.default.addObserver(self,
                                             selector: #selector(applicationDidBecomeActive),
                                             name: UIApplication.didBecomeActiveNotification,
                                             object: nil)
    }
    
fileprivate  func removeObservers() {
        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }
    
@objc fileprivate func applicationDidBecomeActive() {
// here do your work
    }

Solution 5 - Ios

Swift 4.2

Add observer-

NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: UIApplication.didBecomeActiveNotification, object: nil)

Remove observer-

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

Handle Event-

@objc func handleEvent() {
}

Solution 6 - Ios

With Swift 4, Apple advises via a new compiler warning that we avoid the use of #selector in this scenario. The following is a much safer way to accomplish this:

First, create a variable that will hold the observer instance (that will be used to cancel it):

var didBecomeActiveObserver: NSObjectProtocol

Then create a lazy var that can be used by the notification:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in
    // Do stuff
} 

If you require the actual notification be included, just replace the _ with notification.

Next, we set up the notification to observe for the app becoming active.

func setupObserver() {
    didBecomeActiveObserver = NotificationCenter.default.addObserver(
                                  forName: UIApplication.didBecomeActiveNotification,
                                  object: nil,
                                  queue:.main,
                                  using: didBecomeActive)
}

The big change here is that instead of calling a #selector, we now call the var created above. This can eliminate situations where you get invalid selector crashes.

Finally, we remove the observer.

func removeObserver() {
    NotificationCenter.default.removeObserver(didBecomeActiveObserver)
}

Solution 7 - Ios

The Combine way:

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)

Solution 8 - Ios

Swift 5 version:

 NotificationCenter.default.addObserver(self,
                                               selector: #selector(loadData),
                                               name: UIApplication.didBecomeActiveNotification,
                                               object: nil)

Removing the observer is no longer required in iOS 9 and later.

Solution 9 - Ios

In Swift 5

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() {
    }

Solution 10 - Ios

If any of you is using SwiftUI:

.onReceive(NotificationCenter.default.publisher(
    for: UIApplication.didBecomeActiveNotification)) { _ in
        print("DID BECOME ACTIVE")
    }
)

Solution 11 - Ios

For Swift5 MacOS, you need to use NSApplication instead of UIApplication.

NotificationCenter.default.addObserver(self,
                                       selector: #selector(applicationDidBecomeActive),
                                       name: (NSApplication.didBecomeActiveNotification),
                                       object: nil)
    }

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
QuestionCalvinView Question on Stackoverflow
Solution 1 - IosReed OlsenView Answer on Stackoverflow
Solution 2 - IosigrekView Answer on Stackoverflow
Solution 3 - IosZorayrView Answer on Stackoverflow
Solution 4 - IosGurjinder SinghView Answer on Stackoverflow
Solution 5 - IosAbhishek JainView Answer on Stackoverflow
Solution 6 - IosCodeBenderView Answer on Stackoverflow
Solution 7 - Ios0llieView Answer on Stackoverflow
Solution 8 - IosBogdan RazvanView Answer on Stackoverflow
Solution 9 - IosNaveen SharmaView Answer on Stackoverflow
Solution 10 - IosRobView Answer on Stackoverflow
Solution 11 - IoscsytsmaView Answer on Stackoverflow