0

I implemented 3D Touch Quick Action in app when call function performActionForShortcutItem in AppDelegate, I triggering by NotificationCenter inside it but not work and call

my Code in AppDelegate:

func application(_ application: UIApplication, performActionFor 
shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping 
(Bool) -> Void) {


    NotificationCenter.default.post(name: Notification.Name("action"), object: nil);

}        

and used it ViewController:

override func viewDidLoad() {
    super.viewDidLoad();


    NotificationCenter.default.addObserver(self, selector: #selector(BaseViewController.didReceiveNotification), name: Notification.Name("action"), object: nil);
}

func didReceiveNotification() {
    let alert = UIAlert(viewController: self);
    alert.content = "NotificationCenter Worked";
    alert.title = "NotificationCenter here!!";
    alert.show();
}
ImanX
  • 789
  • 6
  • 23
  • 1
    Is your ViewController Loaded at the time you post your Notification? Because the addObserver must be executed before you post something... Did you try to print() if viewDidLoad is Executed before performActionForShortcutItem? – Dennis Weidmann Mar 24 '18 at 16:47

2 Answers2

2

The problem is that ViewController is not yet loaded so the observer is not yet add to it

 NotificationCenter.default.addObserver(self, selector: #selector(BaseViewController.didReceiveNotification), name: Notification.Name("action"), object: nil);

you can try to set a boolean value insideperformActionForshortcutItem and check it inside viewDidAppear of ViewController

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
2

Your Problem is like Sh_Khan said, that you can't post on AppDelegate to a ViewController, because at this time your ViewController didn't subscribe to the Notification...

You need to do something like this:

In your AppDelegate

    func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping(Bool) -> Void) {
            UserDefaults.standard.set(true, forKey: "openedByShortcutAction")
            UserDefaults.standard.synchronize()
        }

In your ViewController:

override func viewDidLoad() {
        super.viewDidLoad()
        if (UserDefaults.standard.bool(forKey: "openedByShortcutAction")) {
            //Your App has been started by selecting your Shortcut Action
        }
    }
Dennis Weidmann
  • 1,942
  • 1
  • 14
  • 16
  • Yes that's right , this is what i already told him in answer (voted) – Shehata Gamal Mar 24 '18 at 17:10
  • @Sh_Khan thanks My friends but I want handle it by `NotificationCenter` and I don't like use flag or var. but no way ! – ImanX Mar 24 '18 at 17:13
  • 1
    Well you can't handle it by NotificationCenter mate :-) – Dennis Weidmann Mar 24 '18 at 17:15
  • Yes, there is no 100% guarantee it that it can be correctly handled by notificationCenter , one way is to use dispatchAfter to delay the postNotification call , but the time you set can span(either more or less than ) the time the viewController is loaded – Shehata Gamal Mar 24 '18 at 17:18