2

So i've implemented universal link in my app and when pressing on a button I open my second app with :

UIApplication.shared.open(aUrl!)

also I'm getting the call in :

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {}

which is an alert.

The question is like the title says..how could I navigate to a specific VC ,(from the FirstApp to the Second which i opened it with universal link), more like mapping a navigation controller stack .

I've writed something like :

        if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MyAdsController") as? MyAdsViewController {
        if let window = self.window, let rootViewController = window.rootViewController {
            var currentController = rootViewController
            while let presentedController = currentController.presentedViewController {
                currentController = presentedController
            }
            currentController.present(controller, animated: true, completion: nil)
        }
    }

but it's an ugly representation, i need something like the hole navigation stack...

And also , can i make a helper class for this if i want to handle more with universal link? Any suggestion are appreciated.

5
  • you mean, you wish to navigate to a specific viewcontroller in the second app that is opened from first app ?
    – Jen Jose
    Commented Mar 1, 2018 at 13:45
  • Yes , exactly . I've edited my question Commented Mar 1, 2018 at 13:46
  • That might hep: medium.com/@stasost/… Commented Mar 1, 2018 at 13:54
  • Is there a reason why you don't use a UINavigationController and reset the stack you want ( navigationController.viewControllers = [vc1, vc2, controllerYouWant] )?
    – Y.Bonafons
    Commented Mar 1, 2018 at 14:03
  • No , not at all, the thing is i don't know how :) Commented Mar 1, 2018 at 14:07

2 Answers 2

1

You need to use the .viewControllers property of your UINavigationController you can do this using setViewControllers(_:animated:) method or modifying directly .viewControllers property where rootViewController will be the viewControllersArray[0] and topViewController will be viewControllersArray[count-1]

This property description and details can be founded in the UINavigationController documentation

viewControllers

Property

The view controllers currently on the navigation stack.

Declaration SWIFT

var viewControllers: [UIViewController]

Discussion The root view controller is at index 0 in the array, the back view controller is at index n-2, and the top controller is at index n-1, where n is the number of items in the array.

Assigning a new array of view controllers to this property is equivalent to calling the setViewControllers:animated: method with the animated parameter set to false.

example

    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let firstViewController = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as? FirstViewController
    let secondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
    let thirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as? ThirdViewController

    self.navigationController?.setViewControllers([firstViewController,secondViewController,thirdViewController], animated: false)
1

Alright so this is less of a Universal Link question and more of a navigation preference. When you are passed a universal link in your continueUserActivity function you should parse it and navigate accordingly from your app delegate. You should really switch your Universal Link handling to Branch since they will handle this for you for free and they pass metadata through a callback instead of link parameters which will make your links more powerful. Anyways...

Start with a UINavigationViewController

This consists of having a rootViewController which should be an instance of your main page. Store this navigation view controller as an instance variable so your app is only dealing with one Navigation view controller on launch. If you're using a storyboard then you can just just get reference to that navigation view controller:

self.nav = self.window?.rootViewController as? UINavigationViewController

Pushing vs presenting a View Controller onto Nav

When you receive a link and determined that you need to bring that user to a new page, you should decide whether to push or present the VC.

Pushing

Pushing is necessary if you would like to maintain that view as part of a stack. For example, if you want to show the user a pair of shoes, you may want to take them into the shoes category, then present them with the shoe detail controller. In this case you could take the user to the home page and push the proper navigation stack onto your UINavigationViewController.

self.nav.popToRootViewController(animated: true)

self.nav.pushViewController(firstController, animated: true)

self.nav.pushViewController(secondViewController, animated: true)

This way your users UINavigationController stack will look like root > firstVC > secondVC and they will have bread crumbs to be able to traverse back through the flow.

Presenting

In the case that you do not want to push a view onto the stack. Maybe you want to present a popup regardless of where they are at in the app and you don't want to mess up their location, you should use present a VC. This will simply present a ViewController over the entire NavigationController without being added to the NavigationController's stack.

self.nav.presentViewController(modalVC, animated:true, completion: nil)

From within that modalVC you can call

self.dismiss(animated: true, completion: nil)

Not the answer you're looking for? Browse other questions tagged or ask your own question.