ios – How to make the app navigate to a certain view when the user launches the app through a notification in SwiftUI?


I am implementing a new feature in the app where a notification is sent from a user to another and when that notification is pressed the user is naviagted to a relevant view.

I was able to make it work only when the app is in running either in the foreground or background. But for some reason it does not want to trigger the Navigationlink when the app is started by the notification.

I believe it has something to do with the func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? ) -> Bool block of code but I am not sure what to do.

final class AppDelegate: NSObject, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self
        
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
        
        application.registerForRemoteNotifications()

        // Check if the app was launched from a remote notification
        if let remoteNotification = launchOptions [UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any] {

                 handleRemoteNotification(remoteNotification)

                }
        
        return true
    }
    
    func handleRemoteNotification(_ userInfo: [AnyHashable: Any]) {
                
        if let destination = userInfo["destination"] as? String {
            if destination == "CertainView" {
                NotificationCenter.default.post(
                    name: Notification.Name("NavigateToCertainView"),
                    object: nil,
                    userInfo: userInfo
                )
            }
        }
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(
        _: UNUserNotificationCenter,
        willPresent _: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        completionHandler([[.banner, .list, .sound]])
    }
    
    func userNotificationCenter(
        _: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let userInfo = response.notification.request.content.userInfo
        
        if let destination = userInfo["destination"] as? String {
            if destination == "CertainView" {
                NotificationCenter.default.post(
                    name: Notification.Name("NavigateToCertainView"),
                    object: nil,
                    userInfo: userInfo
                )
            }
        }
        completionHandler()
    }
}

Here is the notification payload just in case its needed for context:

let body: [String: Any] = [
    "to": fcmToken, // a test device
    "notification": [
    "title": "You have a new message!",
    "body": "Check out the new message.", 
   ],
    "data": [
          "destination": "CertainView", 
       ],
    ]

I have an .onAppear in my HomeView that runs an addObserver to check for a posted notifications:

.onAppear {
    NotificationCenter.default.addObserver(
        forName: Notification.Name("NavigateToHymnsView"),
        object: nil,
        queue: nil
        ) { _ in
            isHymnsViewActive = true
             print("Notification received. Navigating to desired view.")
           }
  }

Which triggers a @State variable which then triggers a NavigationLink to naviagte:

NavigationLink(
   destination: CertainView(), // Destination view
   isActive: $isHymnsViewActive,
   label: {
           EmptyView() // EmptyView as the label; navigation is triggered programmatically
          })
         .hidden()

Again, everything works as intended when the app is already running and the notification is pressed but when the app is launched from that notification, the app just opens and nothing happens.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img