Search code examples
iosswiftfirebaseerror-handlingnsexception

Swift Firebase Notifications "libc++abi.dylib: terminating with uncaught exception of type NSException"


I am trying to add Firebase Notifications to my app. I am getting a error before my app even starts. Also, whats the difference between calling notifications from my app vs Firebase? Is it not possible to call notifications from my app which is why firebase notifications is needed? I am very ignorant on notifications and a simple summary would be great. Thanks

import UIKit
import Firebase
import GoogleSignIn
import FBSDKCoreKit
import TwitterKit
import IQKeyboardManagerSwift
import OAuthSwift
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {

var window: UIWindow?

static var shared: AppDelegate { return UIApplication.shared.delegate as! AppDelegate }

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    FirebaseApp.configure()

    GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self

    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

    IQKeyboardManager.sharedManager().enable = true

    Twitter.sharedInstance().start(withConsumerKey: "6nQtUKZChHOJ0iNjUsHuJoMrH", consumerSecret: "CEEfZPMx4BSNel4eknivDCHALrWpxR5NBpjgtxmYxzFipTPJcz")


    FirebaseApp.configure()
    application.registerForRemoteNotifications()
    requestNotificationAuthorization(application: application)
    if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] {
        NSLog("[RemoteNotification] applicationState: \(applicationStateString) didFinishLaunchingWithOptions for iOS9: \(userInfo)")
        //TODO: Handle background notification
    }


    return true
}

var applicationStateString: String {
    if UIApplication.shared.applicationState == .active {
        return "active"
    } else if UIApplication.shared.applicationState == .background {
        return "background"
    }else {
        return "inactive"
    }
}

func requestNotificationAuthorization(application: UIApplication) {
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: {_, _ in })
    } else {
        let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(settings)
    }
    }

    // The callback to handle data message received via FCM for devices running iOS 10 or above.
    @objc(applicationReceivedRemoteMessage:) func application(received remoteMessage: MessagingRemoteMessage) {
    print(remoteMessage.appData)
}


func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    let isFBOpenUrl = FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
    let isGoogleOpenUrl = GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation)

    if isFBOpenUrl { return true }
    if isGoogleOpenUrl { return true }

    return false
}


func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    if (url.host == "oauth-callback") {
        OAuthSwift.handle(url: url)
    }
    return Twitter.sharedInstance().application(app, open: url, options: options)

    return true
}

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
    // ...
    if error != nil {
        // ...
        return
    }

    guard let authentication = user.authentication else { return }
    let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken)
    // ...
}


func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
    // Perform any operations when the user disconnects from app here.
    // ...
}


func applicationWillResignActive(_ application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}

func applicationDidEnterBackground(_ application: UIApplication) {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

func applicationWillEnterForeground(_ application: UIApplication) {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// iOS10+, called when presenting notification in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo
    NSLog("[UserNotificationCenter] applicationState: \(applicationStateString) willPresentNotification: \(userInfo)")
    //TODO: Handle foreground notification
    completionHandler([.alert])
}

  // iOS10+, called when received response (default open, dismiss or custom action) for a notification
   func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    NSLog("[UserNotificationCenter] applicationState: \(applicationStateString) didReceiveResponse: \(userInfo)")
    //TODO: Handle background notification
    completionHandler()
}
}

 extension AppDelegate : MessagingDelegate {
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    NSLog("[RemoteNotification] didRefreshRegistrationToken: \(fcmToken)")
}

// iOS9, called when presenting notification in foreground
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    NSLog("[RemoteNotification] applicationState: \(applicationStateString) didReceiveRemoteNotification for iOS9: \(userInfo)")
    if UIApplication.shared.applicationState == .active {
        //TODO: Handle foreground notification
    } else {
        //TODO: Handle background notification
    }
}
}

Solution

  • Remove reference of your "GoogleService-Info.plist" file and again add it using add to file option...

    for more watch it carefully