1

In my application I need that each controller showed popup when some event happens.

I can listen to this NSNotification in each controller. But I don't want to duplicate the code.

Is there a way to listen to NSNotification and do some actions globally?

Ostap Maliuvanchuk
  • 1,125
  • 2
  • 12
  • 32

2 Answers2

1

You can write a custom UIViewController that listens to notifications, and then make all other UIViewControllers subclass it. That way they all can listen, and you do not duplicate code. I think this should work:

class ListeningViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("derp"), name: "herp", object: nil)
    }

    func derp() {
        print("herp-derp")
    }
}

class FunctionalViewController: ListeningViewController {
    override func derp() {
        print("i can also derp")
    }
}

or you can write a UIViewController extension:

extension UIViewController {
    public func startListenintToNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("derp"), name: "herp", object: nil)
    }

    func derp() {
        print("herp-derp")
    }
}

And just call the startListeningToNotificationsMethod once in every ViewController

Snacks
  • 513
  • 4
  • 22
  • I was also thinking about making a subclass of UIViewController. But if my controller already is a subclass of another third party controller class then it wouldn't work as I understand. – Ostap Maliuvanchuk Nov 27 '15 at 09:13
  • The extension looks better to me for two reasons : 1. You still get to decide which VC will be listening to this notification (there may come a time when you will not want to use it. 2. What OP said in previous comment :) – Losiowaty Nov 27 '15 at 09:14
  • Yes, it all depends on the app architecture :) In this case, i also think that an extension would be better. – Snacks Nov 27 '15 at 09:16
1

I'd suggest you listen the notification in your AppDelegate.

Once you have catch the notification, present the popup on the top most view controller.

You can determine the top most view controller as described in this question.

Or just use another third-party helper: PPTopMostController.

The following example uses PPTopMostController to determine the top most view controller:

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [[NSNotificationCenter defaultCenter] addObserverForName:NotificationName
                                                      object:nil
                                                       queue:[NSOperationQueue mainQueue]
                                                  usingBlock:^(NSNotification *notification) {
                                                      UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Good News"
                                                                                                                     message:@"Your friend Ostap Maliuvanchuk sent you a gift!"
                                                                                                              preferredStyle:UIAlertControllerStyleAlert];
                                                      [alert addAction:[UIAlertAction actionWithTitle:@"OK"
                                                                                                style:UIAlertActionStyleCancel
                                                                                              handler:^(UIAlertAction *action) {
                                                                                                  // show the user the gift
                                                                                                  // maybe open a new controller
                                                                                              }]];

                                                      [[UIViewController topMostController] presentViewController:alert
                                                                                                         animated:YES
                                                                                                       completion:nil];
                                              }];
    return YES;
}
Community
  • 1
  • 1
Cheng-Yu Hsu
  • 1,029
  • 7
  • 11