Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly redirect to a view controller inside tab bar's navigation controller when push notification is clicked

I have a tabBar. Each of its tabs' ViewControllers have been embedded inside their respective NavigationControllers.

Hierarchy:

Tabbarcontroller --> NavigationController --> VC1 --> VC2 -->...VCn (for tab1)

I have to redirect to one of the viewcontrollers say VC2 when i click on push notifications. The code i am using is as follows.

let navigationController = UINavigationController()
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
if let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as? ChatViewController {
    navigationController.viewControllers = [chatViewController]
    window?.rootViewController = navigationController
}

By using this, I am redirected to the respective ViewController. However, i am not able to get back to the tabBar. So is it possible to redirect in such a way that it allows me the get back to the tab bar, thus providing the same hierarchy as in the UI?

EDIT:

The image below shows my layout.

enter image description here

I would like to accomplish the following:

  1. When the user taps the push notification, the app should be directed to VC-B. *It should not create new object for VC-B and add to the navigation stack if VC-B is already on top of navigation stack.

  2. If the app had been terminated and the user taps on the notification, it should open VC-B.

For determining if the app had been terminated, I set a flag as:

func applicationWillTerminate(_ application: UIApplication) {
    UserDefaults.standard.set(true, forKey: UserDefaultsKey.isTerminated)
}

This flag is set false at the end of didFinishLaunchingWithOptions function.

For redirection, I check this flag to determine if the app had been terminated:

func performRedirectionToSuitableViewController(userInfo: [AnyHashable: Any]) {
  
    let isTerminated = UserDefaults.standard.object(forKey: UserDefaultsKey.isTerminated) as! Bool
    
    if isTerminated {
        
        let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
        
        let tab = storyboard.instantiateViewController(withIdentifier: "tabBar") as! UITabBarController
        
        tab.selectedIndex = 0
        
        let nav = tab.viewControllers![0] as! UINavigationController
        
        let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as! ChatViewController
        
        chatViewController.chatThreadId = userInfo["thread_id"] as? String
        
        nav.pushViewController(chatViewController, animated: true)

    } else {

        if let tab = window?.rootViewController?.presentedViewController as? UITabBarController {

            let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)

            let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as! ChatViewController
                
            chatViewController.chatThreadId = userInfo["thread_id"] as? String
               
            if let nav = tab.selectedViewController as? UINavigationController {
                   
                nav.pushViewController(chatViewController, animated: true)
            }     
        }
    }
}

With this code, my first requirement is partially fulfilled. Need to determine if the viewcontroller is at the top of the navigation stack.

And, in the case of terminated app, clicking the push notification opens the tab bar, with the default selection index being selected.

I have spent several days trying to fix this. But cannot get it work.

like image 426
Sujal Avatar asked Nov 08 '22 03:11

Sujal


1 Answers

I suppose you have to do something like this:

let tabBar: UITabBarController // get your tab bar
tabBar.selectedIndex = 0 // eg. zero. To be sure that you are on correct tab
if let navigation = tabBar.viewControllers?[tabBar.selectedIndex] as? UINavigationController {
    let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
    if let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as? ChatViewController {
        navigation.pushViewController(chatViewController, animated: true)
    }
 }
like image 182
Andrew Bogaevskyi Avatar answered Nov 17 '22 22:11

Andrew Bogaevskyi