iosswiftfirebase-cloud-messagingapple-push-notifications

How can i present a specific view in push notification when get response?


i want to create a protocol in appDelegate and use that in push notification to present a view when app in foreground or when user open app, i created one but it doesn't work

this is App Delegate :


import Firebase
import FirebaseAppCheck
import FirebaseCore
import FirebaseFirestore
import FirebaseMessaging
import FirebaseStorage
import GoogleMaps
import IQKeyboardManagerSwift
import UserNotifications

protocol AppDelegateProtocol {
    func showRequestView()
}

class AppDelegate: UIResponder, UIApplicationDelegate {

let googleApiKey = Constants.googleApiKey
    var gcmMessageIDKey = "gcm.message_id"

    var window: UIWindow?
    var delegate: AppDelegateProtocol?

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

        let providerFactory = AppCheckDebugProviderFactory()
        AppCheck.setAppCheckProviderFactory(providerFactory)

        FirebaseApp.configure()

        Messaging.messaging().delegate = self
        Messaging.messaging().isAutoInitEnabled = true

        IQKeyboardManager.shared.enable = true

        UNUserNotificationCenter.current().delegate = self

        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: { _, _ in }
        )

        application.registerForRemoteNotifications()

        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        printLog(userInfo)
        
        delegate?.showRequestView()
    }

func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error)
    {
        print("Unable to register for remote notifications: \(error.localizedDescription)")
    }

    // This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
    // If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
    // the FCM registration token.
    func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
    {
        print("APNs token retrieved: \(deviceToken)")

        // With swizzling disabled you must set the APNs token here.
        // Messaging.messaging().apnsToken = deviceToken
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification) async
        -> UNNotificationPresentationOptions
    {
        printLog("will present")
        // Handle the push notification

        // App is in the foreground, handle the notification without presenting a new view controller
        delegate?.showRequestView()

        let userInfo = notification.request.content.userInfo

        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)

        // [START_EXCLUDE]
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            printLog("Message ID: \(messageID)")
            printLog("User info: \(userInfo)")
        }
        // [END_EXCLUDE]

        // Print full message.

        // Change this to your preferred presentation option
        return [[.badge, .sound]]
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse) async
    {
        printLog("did Receive")

        let userInfo = response.notification.request.content.userInfo

        // [START_EXCLUDE]
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            printLog("this is did Receive")
            printLog("Message ID: \(messageID)")
        }
        // [END_EXCLUDE]

        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)

        // Print full message.
        printLog(userInfo)
    }
}

// [END ios_10_message_handling]

extension AppDelegate: MessagingDelegate {
    // [START refresh_token]
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("Firebase registration token: \(String(describing: fcmToken))")
        Constants.fcmTokenValue = fcmToken ?? ""

        let dataDict: [String: String] = ["token": fcmToken ?? ""]
        NotificationCenter.default.post(
            name: Notification.Name("FCMToken"),
            object: nil,
            userInfo: dataDict
        )
        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }
}

view controller:


class TransportRequestViewController: UIViewController,AppDelegateProtocol {

    let appDelegate = AppDelegate()

    override func viewDidLoad() {
        super.viewDidLoad()
        appDelegate.delegate = self
        printLog("transportRequest VIEW DID LOAD!")
        // Do any additional setup after loading the view.
    }
    

    
    func showRequestView() {
        printLog("showRequestView functionnnn")
        let storyboard = UIStoryboard(name: "transportRequest", bundle: .main)
        let vc = storyboard.instantiateViewController(identifier: "transportRequest") as! TransportRequestViewController
        present(vc, animated: true, completion: nil)
    }

and when i receive push notification, the view doesn't present even printLog("showRequestView functionnnn") didn't print in console.


Solution

  • in view controller instead of let appDelegate = AppDelegate() i had to write like this private let appDelegate = UIApplication.shared.delegate as! AppDelegate

    otherwise the protocol delegate in AppDelegate not working.