15

I'm implementing a ViewController with the following requirement: If the user returns to the app after 15 minutes, the view should reload the data.

I was thinking on using viewDidDisappear to save the timestamp when the app went to background and viewDidAppear for checking previously saved values and refresh if needed, but this methods are not getting called when switching between apps.

How can I solve this in a easy way?

Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
Addev
  • 31,819
  • 51
  • 183
  • 302

5 Answers5

29

use UIApplicationDidBecomeActive for resume and UIApplicationWillResignActive for handle goes background

SwiftUI

Text("check application state!")
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
                    print("User received on  willResignActiveNotification!")
                }
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                    print("User received on  didBecomeActiveNotification!")
                }

Swift 5.x > above

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

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.openAndCloseActivity), name: UIApplication.willResignActiveNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.openAndCloseActivity), name: UIApplication.didBecomeActiveNotification, object: nil)
}

@objc func openAndCloseActivity(_ notification: Notification)  {
    if notification.name == UIApplication.didBecomeActiveNotification{
        // become active notifictaion
    }else{
        // willResignActiveNotification
    }
    
}

Swift 5.x < below

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
     NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.closeActivityController), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.openactivity), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
   
    
}

and handle the method as

func closeActivityController()  {
    
    
}

func openactivity()  {
    
    //view should reload the data.
}

other notification types are

extension NSNotification.Name { 
@available(iOS 4.0, *)
public static let UIApplicationDidEnterBackground: NSNotification.Name

@available(iOS 4.0, *)
public static let UIApplicationWillEnterForeground: NSNotification.Name

public static let UIApplicationDidFinishLaunching: NSNotification.Name

public static let UIApplicationDidBecomeActive: NSNotification.Name

public static let UIApplicationWillResignActive: NSNotification.Name

public static let UIApplicationDidReceiveMemoryWarning: NSNotification.Name

public static let UIApplicationWillTerminate: NSNotification.Name

}
Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
  • 1
    This is a duplicate of https://stackoverflow.com/questions/24910765/ios-nsnotificationcenter-to-check-whether-the-app-came-from-background-to-foregr – Lorenzo B Aug 30 '17 at 08:37
  • @LorenzoB - are you seen my answer i used the name `UIApplicationWillEnterForeground` or `UIApplicationWillResignActive` – Anbu.Karthik Aug 30 '17 at 08:38
  • @LorenzoB - i am not copied the answer , if you think its dupliacte question you can mark as duplicate but answer is not duplicate – Anbu.Karthik Aug 30 '17 at 08:39
  • I do not think is copied. Just to highlight that OP question is really similar to the one I linked. – Lorenzo B Aug 30 '17 at 08:41
  • 1
    @LorenzoB - sorry my bro, i think u said my answer is duplicate – Anbu.Karthik Aug 30 '17 at 08:41
  • Thanks for your answer Anbu, will try it right now, but, if you unregister on viewWillDisappear then you should register in the viewWillAppear right? – Addev Aug 30 '17 at 08:45
  • @Adrime - absolutely corret, if you are in the same VC, then no need, else you need to move code from viewdidload to viewwillappear, thats all bro – Anbu.Karthik Aug 30 '17 at 08:47
  • These notification names are outdated in iOS 15.0. – Cable W Dec 21 '21 at 01:50
  • @CableW - thankyou for valuable message, answer has been updated. – Anbu.Karthik Dec 21 '21 at 05:04
19

Swift 5

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(appBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)

Methods :

@objc func appMovedToBackground() {
       print("App moved to background!")
    }
@objc func appBecomeActive() {
       print("App become active")
    }

To remove observers

override func viewWillDisappear(_ animated: Bool) {
      let notificationCenter = NotificationCenter.default
        notificationCenter.removeObserver(self, name:UIApplication.willResignActiveNotification, object: nil)
        notificationCenter.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }
Emin Turk
  • 350
  • 3
  • 13
0

UIApplicationDelegate has these two functions:

applicationDidEnterBackground(_:)
applicationDidBecomeActive(_:)

These could well be what you need.

Tom E
  • 1,530
  • 9
  • 17
0

Objective-C

- (void)viewDidLoad {
     [[NSNotificationCenter defaultCenter] addObserver:self
   selector:@selector(appMovedToBackground:)
       name:UIApplicationDidEnterBackgroundNotification
     object:nil];

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

- (void)appMovedToBackground:(NSNotification *) notification  {
    NSLog(@"App Moved To Background");
}

- (void)appBecomeActive:(NSNotification *) notification {
    NSLog(@"App become active");
}

Don't forget to clear notifications when view gets disappear

0

If interested here is a RxSwift version

NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification).subscribe(onNext: { [weak self] _ in
            
}).disposed(by: disposeBag)

NotificationCenter.default.rx.notification(UIApplication.willResignActiveNotification).subscribe(onNext: { [weak self] _ in

}).disposed(by: disposeBag)

Dario Pellegrini
  • 1,652
  • 14
  • 15