0

This is how my app is structured.

MainViewController (UITabViewController) --> VC1 (UIViewController) --> AddVC (UIViewController)  
                                         --> VC2 (UIViewController)  
                                         --> VC3 (UIViewController)

I want to add quick actions to my app, so I can access the AddVC when I press the action button from AppDelegate.
VC1 has an Add button which uses a segue to go to AddVC.

This is how I am trying to do: create the AddVC view controller and then MainViewController and from this I retrieve the VC1 with which I try to present the AddVC screen.

func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    let vc = storyboard.instantiateViewController(withIdentifier: "AddVC") as! AddVC

    switch shortcutItem.type {
    case "Add":
        let mainVC = app?.getRootViewController() as! MainViewController
        let vc1 = mainVC.getVC1()
        DispatchQueue.main.async {
            vc1?.present(vc, animated: true, completion: nil)
        }
}

When I do this, it always go to VC1 view controller, but not to the AddVC, so the segue is not performed.
I also tried using performSegue inside the DispatchQueue, same effect.

Anyone has an idea how can I make this work ?

Adrian
  • 19,440
  • 34
  • 112
  • 219

1 Answers1

0

I'm guessing this is a timing issue.

The hacky way to test is just to delay your Dispatch for a second (or however long it takes your app to launch) and see if it works then.

A better solution would be to add a shouldGoToAddVC flag to VC1 and do your present after viewDidAppear.

GetSwifty
  • 7,568
  • 1
  • 29
  • 46
  • I am not sure I understand. My app is already started. I just exit it and 3D touch on icon and press my button. I am not sure why there is a timing issue. – Adrian Oct 18 '17 at 20:37
  • Because VC1 isn't on the screen yet. Until the app's full activation completions and the animation from your home screen the the app completes, it won't be able to navigate to a new VC. Also keep in mind that your app may not be alive whatsoever when a quick action takes place. – GetSwifty Oct 18 '17 at 20:52
  • Oh, I see what you mean. I added a sleep(3) and I get this warning: Attempt to present on whose view is not in the window hierarchy! – Adrian Oct 18 '17 at 21:05
  • Sounds like VC1 wasn't on screen – GetSwifty Oct 18 '17 at 21:15
  • Yep, I tried your solution, but instead of viewDidAppear, I need a custom notificaiton for when app will enter foreground, because viewDidAppear will not get called in my case. Still the issue is, that the event is called before I set the flag from AppDelegate. – Adrian Oct 18 '17 at 21:19
  • Did you test it? AFAIK `viewDidAppear` should be called when you come from background. – GetSwifty Oct 18 '17 at 21:22
  • I test it, it doesn't. I also search on the internet, viewWillAppear/viewDidAppear will not get called when the app goes to background and comes back to foreground. – Adrian Oct 18 '17 at 21:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157030/discussion-between-peejweej-and-kobe). – GetSwifty Oct 18 '17 at 21:44
  • Huh...I guess I'm crazy 0:-) registering for `UIApplicationWillEnterForeground` will probably do what you need: https://stackoverflow.com/questions/25716012/triggering-a-specific-action-when-the-app-enters-foreground-from-a-local-notific – GetSwifty Oct 18 '17 at 21:48
  • Yeah, I already use that notification, but the issue is, when my app enters foreground, this event is triggered and only after this, the AppDelegate code is called where I set the flag to true. So at the time, the enter foreground event is fired, the flag is still false. – Adrian Oct 19 '17 at 08:57