0

I want to navigate to a specific viewcontroller when the I click on a push notification.

I have written this code in my didReceiveRemoteNotification method.

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewController(withIdentifier: "deals") as! FYIDealsVC
        let naviVC:UINavigationController? = self.window?.rootViewController?.revealViewController().frontViewController as? UINavigationController
        naviVC?.pushViewController(vc, animated: true)
}

But it's giving me this error which crashes the app.

fatal error: unexpectedly found nil while unwrapping an Optional value

There are many posts with navigation controller or just presenting the viewcontroller. But I want to navigate to the specific view with reveal.

Any help would be highly appreciated.

KENdi
  • 7,576
  • 2
  • 16
  • 31
NavodaP
  • 218
  • 3
  • 18
  • 1
    Are you sure that the storyboard ID of the given screen is "deals" and that it has the class `FYIDealsVC`? – Tamás Sengel Aug 29 '17 at 09:04
  • Yes, in this line only it breaks down let naviVC:UINavigationController? = self.window?.rootViewController?.revealViewController().frontViewController as? UINavigationController – NavodaP Aug 29 '17 at 09:08
  • are you sure you are getting object of navigation controller debug this line i think you are getting nil in this line self.window?.rootViewController?.revealViewController().frontViewController as? UINavigationController – Pushpendra Aug 29 '17 at 09:11
  • Hi, yes im getting nil in that line – NavodaP Aug 29 '17 at 09:15
  • i have another solution for this try with window.rootviewcontroller or you can use notificationcenter to navigate – Pushpendra Aug 29 '17 at 09:21
  • sharing my way to achieve this. – Pushpendra Aug 29 '17 at 09:22

2 Answers2

2

here is a another solution for this Try this:-

First Option :-

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
     let vc = storyboard.instantiateViewController(withIdentifier: 
    "deals") as! FYIDealsVC

  // setup revelview controller and root with window 

    self.window?.rootViewController = //object of revelViewController
    self.window?.makeKeyAndVisible()

Second option :-

 //  in Landing Screen from where you can easily navigate to the target 
  viewcontroller :- 

in Landing VC:-

   viewdidload:- 
            NotificationCenter.default.addObserver(self, selector: 
    #selector(self.navigationForNotification(notification:)), name: 
   NSNotification.Name(rawValue:PushNavigationIdentifier), object: nil)


// Selector Method :-

 func navigationForNotification(notification:Notification) {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: 
 "deals") as! FYIDealsVC
 self.navigationController?.pushViewController(vc, animated: true)  
}


 in appDelegate :- 
   func application(_ application: UIApplication, 
   didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
                  NotificationCenter.default.post(name: 
   NSNotification.Name(PushNavigationIdentifier), object: userInfo)

   }
Pushpendra
  • 976
  • 6
  • 13
  • Hi thanks for the answers. The first one doesn't seem to work and regarding the second, it's working . But you can add observer to only one class. Otherwise it will be called multiple times. I need it be called in every class. – NavodaP Aug 29 '17 at 11:05
  • define only in landing screen and make sure observer should add only once .set a bool with userdefault change the value when observer added. – Pushpendra Aug 29 '17 at 11:14
  • yeah, but if the user is in another class , that class fails to catch that notification and do the function required. I want whatever the class catch the notification , but execute the required function just once. – NavodaP Aug 29 '17 at 11:34
  • are you using SWrevelvc ? – Pushpendra Aug 29 '17 at 11:59
  • Actually the prob exists with me too. Even if I am adding NotificationCenter on the basecontroller then in that case it is calling but unable to navigate to the next screen when App in in active state, for this what I have done I have added the observer for every screen and removed the observer from ViewWillDisappear. But if it is background then it was working fine. – Prakash Aug 29 '17 at 12:11
  • is target screen is added on side menu.you are accessing FYIDealsVC screen from side menu. – Pushpendra Aug 29 '17 at 12:15
  • if you are switching view from side menu then follow this link to change programatically viewcontroller https://stackoverflow.com/questions/21096326/swrevealviewcontroller-manually-switch-to-another-view – Pushpendra Aug 29 '17 at 12:21
  • Hi, the NotificationCenter approach worked for me along with @Prakash's answer. I have added a base view controller. With that I could add and remove notification observers in ViewDidApppear and ViewWillDisappear methods to all the classes. Thanks a lot! – NavodaP Aug 30 '17 at 05:43
  • @NavodaP we are here to help and guide each other. It's a part of programming. – Prakash Aug 30 '17 at 07:57
0

Looks like error happens when you force unwrap FYIDealsVC. Can you use

let vc = FYIDealsVC()

instead of

let vc = storyboard.instantiateViewController(withIdentifier: "deals") as! FYIDealsVC

Stacy Smith
  • 490
  • 5
  • 11