-1

I am developing live chat app with Firebase so everything works fine for me but I am redirecting directly to viewcontroller as per notification type and I am redirected successfully but the issue is that when app launch first time than I am getting crash and get an error like below

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Here is my code for didReceiveRemoteNotification

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        let notificationType = userInfo["notification_type"] as! String //i am getting crash here
        if notificationType == "news_notification"{
            let rootViewController = self.window?.rootViewController as! UINavigationController

            let storyboard = UIStoryboard(name: "Settings", bundle: nil)
            let VC = storyboard.instantiateViewController(withIdentifier: "NewsDetailViewController") as! NewsDetailViewController
            if let aps  = userInfo["aps"] as? NSDictionary{
                if let alert = aps["alert"] as? NSDictionary{
                    if let body = alert["body"] as? String{
                        print(body)
                        VC.name1 = body
                    }
                    if let title = alert["title"] as? String{
                        print(title)
                        VC.name = title
                    }
                }
            }
            VC.vcValue = "1"
            rootViewController.pushViewController(VC, animated: true)

        }
    }

if I comment this code and then login successfully after login I uncomment this code that its work fine but only first-time launch I am getting error

Yash R
  • 247
  • 2
  • 19
Vishal Parmar
  • 615
  • 4
  • 31

3 Answers3

2

Then that key doesn't exist do , use guard

 print(userInfo) // print to see content 
 guard let notificationType = userInfo["notification_type"] as? String else { return }
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
1

I think you are getting navigation controller nil try this

guard let rootViewController = self.window?.rootViewController as? UINavigationController else { return }
Vishal Parmar
  • 615
  • 4
  • 31
Neeraj
  • 91
  • 3
1

You are force unwrapping something thats nil, you are doing it a lot, and you just pyramid if's on top of eachother which is also bad practice.

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    let storyboard = UIStoryboard(name: "Settings", bundle: nil)

    guard let notificationType = userInfo["notification_type"] as? String,
        notificationType == "news_notification",
        let rootViewController = self.window?.rootViewController as? UINavigationController,
        let vc = storyboard.instantiateViewController(withIdentifier: "NewsDetailViewController") as? NewsDetailViewController,
        let aps  = userInfo["aps"] as? NSDictionary else {return}

    if let body = alert["body"] as? String{
        print(body)
        VC.name1 = body
    }
    if let title = alert["title"] as? String{
        print(title)
        VC.name = title
    }
    VC.vcValue = "1"
    rootViewController.pushViewController(VC, animated: true)
}

There is a cleaned version. 2 great rules to follow:

1: If you are not 100% sure that the value will always exist don't force unwrap it with !

2: If ypu don't have an else condition, you might as well use guard to avoid pyramids.

Vollan
  • 1,887
  • 11
  • 26