admin管理员组

文章数量:1221311

Is it possible to know if the app was launched/opened from a push notification? in swiftUI app iOS 15+

If it is possible how to get that push notification details

here is my App Delegate code:

class AppDelegate: NSObject, UIApplicationDelegate {
@ObservedObject private var notificationHandler = PushNotificationHandler()
var viewModel = PendingCommandsViewModel()
var launchNotification: \[AnyHashable: Any\]?
let gcmMessageIDKey = "gcm.message_id"

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        // Setting Up Cloud Messging..
        Messaging.messaging().delegate = self
        
        // Setting Up Notifications...
        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, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        if let remoteNotification = launchOptions?[.remoteNotification] as? [AnyHashable: Any] {
            launchNotification = remoteNotification
           }
        return true
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        if let notificationData = launchNotification{
            NotificationCenter.default.post(name: .appOpenedOnNotificationClick, object: nil, userInfo: notificationData)
            launchNotification = nil
        }
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
           // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        print(userInfo)
        completionHandler(UIBackgroundFetchResult.newData)
    }
    
    // need to implement this methods in order to receive Notifications...
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Unable to register for remote notifications: \(error.localizedDescription)")
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            Messaging.messaging().apnsToken = deviceToken
    }

}

// Cloud Messging...
extension AppDelegate: MessagingDelegate{
func messaging(\_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {

        let dataDict: [String: String] = ["token": fcmToken ?? ""]
        UserDefaults.standard.set(fcmToken ?? "", forKey: "DeviceToken")
        NotificationCenter.default.post(
            name: Notification.Name("FCMToken"),
            object: nil,
            userInfo: dataDict
        )
    }

}

// User Notifications... \[InApp Notifications...\]
extension AppDelegate: UNUserNotificationCenterDelegate{
func userNotificationCenter(\_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -\> Void) {
let userInfo = notification.request.content.userInfo

        // Do something with message ID
        if let messageID = userInfo[gcmMessageIDKey] {
            print("message ID: \(messageID)")
        }
        
        // Print full message.
        print("Push Notification Response --> \(userInfo)")
        viewModel.receivedNotification = userInfo
            NotificationCenter.default.post(name: Notification.Name("DidReceiveNotification"), object: nil, userInfo: userInfo)
    
        
        // Change this to your preferred presentation option
        completionHandler([[.banner,.alert, .badge, .sound]])
    }
    
    // This function will be called right after user tap on the notification
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Did tap response ---> \(response.notification.request.content.userInfo)")
        let selectedNotificationRes = response.notification.request.content.userInfo
        NotificationCenter.default.post(name: Notification.Name("DidTapOnNotification"), object: nil, userInfo: selectedNotificationRes)
        print("NOtification tapped")
        //        onTapReceivedNotificationHanlde()
        completionHandler()
    }

}

Here below is my Main app file code:

@main
struct PrepareApp: App {
var token: String? = UserDefaults.getAccessToken()
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
let persistenceController = CoreDataStack.shared
@StateObject var selectedQuestionIndex = SelectedQuestionIndex()

    @StateObject private var networkMonitor = NetworkMonitor()
    @Environment(\.scenePhase) var scenePhase
    var body: some Scene {
        WindowGroup {
            SplashView()
                    .environmentObject(selfworkMonitor)
                    .environmentObject(self.selectedQuestionIndex)
                    .environment(\.managedObjectContext, persistenceController.container.viewContext)
    }

}
}

here below is my Splash views code:

struct SplashView: View {

    @StateObject private var viewModel = SplashViewModel()
    var launchNotification: [AnyHashable: Any]?
    @EnvironmentObject var networkMonitor: NetworkMonitor
    @EnvironmentObject var selectedQuestionIndex : SelectedQuestionIndex
    @State private var showAlert = false
       @State private var notificationMessage: String = ""
    
    var body: some View {
        let screenWidth = UIScreen.main.bounds.width
        let firstImageWidth = deviceWidth * 0.2
        let secondImageWidth = deviceWidth * 0.5
        let largeDevicesOffset = (firstImageWidth - secondImageWidth) / 1.5
        ZStack {
            
            switch viewModel.splashViewState {
            case .loadingSplash:
                
                HStack(spacing: 0) {
                    if viewModel.showSingleLogo{
                        Image("ic_SCOR_Logo")
                            .resizable()
                            .frame(width: secondImageWidth, height: deviceWidth * 0.2)
                        Image("ic_ENXT_Logo")
                            .resizable()
                            .frame(width: firstImageWidth, height: deviceWidth * 0.2)
                    }else{
                        Image("ic_ENXT_Logo")
                            .resizable()
                            .offset(x: viewModel.circleScale > 1 ? (secondImageWidth) : -secondImageWidth )
                            .frame(width: firstImageWidth, height: deviceWidth * 0.2)
                        Image("ic_SCOR_Logo")
                            .resizable()
                            .offset(x: viewModel.circleScale > 1 ? largeDevicesOffset : secondImageWidth )
                            .frame(width: secondImageWidth, height: deviceWidth * 0.2)
                    }
                }
                .fullScreenCover(item: $viewModel.showAppUpdates, content: { appUpdate in
                    withAnimation(.none) {
                        AppUpdateView(appUpdateModel: appUpdate,
                        onUpdateClick: {
                           // viewModel.showAppUpdates = nil
    
                            viewModel.openAppStore()
                            //viewModel.onLaterClicked()
    
                        }, onLaterClick: {
                            //viewModel.showAppUpdates = nil
                            viewModel.onLaterClicked()
                        })
                        
                    }
                })
                .background(
                    Circle()
                        .fill(Color.blueColour)
                        .scaleEffect(viewModel.circleScale)
                        .frame(width: deviceWidth * 0.5, height: deviceWidth * 0.5))
                .onAppear {
                    
                    withAnimation(Animation.easeInOut(duration: 2.0)) {
                        viewModel.circleScale = 10.0
                        viewModel.swapImages.toggle()
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1.8){
                            viewModel.showSingleLogo.toggle()
                            viewModel.checkInAppUpdateAPI(isConnected: selfworkMonitor.isConnected)
                            
                        }
                    }
                }.transaction({ transaction in    transaction.disablesAnimations = true
                })
                
            case .noUserLoggedIn:
                EntityValidationView()
                    .environmentObject(selfworkMonitor)
                    .environmentObject(self.selectedQuestionIndex)
                
            case .userLoggedIn:
                CustomTabBar()
                    .environmentObject(selfworkMonitor)
                    .environmentObject(self.selectedQuestionIndex)
            }
            
        }.ignoresSafeArea()
    }

}

and hereBelow is my custom tab bar view code

struct CustomTabBar: View {
@StateObject var viewModel: CustomTabBarViewModel = CustomTabBarViewModel()
@StateObject private var pcViewModel = PendingCommandsViewModel()
@StateObject private var notificationHandler = PushNotificationHandler()
@EnvironmentObject private var networkMonitor: NetworkMonitor
@Environment(.scenePhase) var scenePhase

    var body: some View {
        AppNavigationBaseView{
            ZStack{
                VStack(spacing: 0) {
                    ZStack {
                        tabContentView()
                    }.frame(maxWidth: .infinity, maxHeight: .infinity)
                    
                    if viewModel.shouldShowTabBar{
                        Divider().foregroundColor(Color.blackColour)
                        HStack(alignment: .top) {
                            TabView(tab: Tab.HOME_VIEW, selectedTab: $viewModel.selectedView){ selectedTab in
                                if(viewModel.selectedView != selectedTab){
                                    viewModel.selectTabView(tab: selectedTab)
                                }
                                // }
                            }.environmentObject(viewModel)
                            TabView(tab: Tab.TIME_LINE_VIEW, selectedTab: $viewModel.selectedView){ selectedTab in
                                if(viewModel.selectedView != selectedTab){
                                    viewModel.viewType = .ET
                                    viewModel.selectTabView(tab: selectedTab)
                                }
                            }.environmentObject(viewModel)
                            TabView(tab: Tab.COURSER_VIEW, selectedTab: $viewModel.selectedView){ selectedTab in
                                if(viewModel.selectedView != selectedTab){
                                    viewModel.selectTabView(tab: selectedTab)
                                }
                            }.environmentObject(viewModel)
                            TabView(tab: Tab.USER_PROFILE_VIEW, selectedTab: $viewModel.selectedView){ selectedTab in
                                if(viewModel.selectedView != selectedTab){
                                    viewModel.selectTabView(tab: selectedTab)
                                }
                            }.environmentObject(viewModel)
                        }.padding(.bottom,24)
                            .frame(maxWidth: .infinity)
                            .frame(height: viewModel.shouldShowTabBar ? nil : 0)
                            .padding(.horizontal, 10)
                    }
                }.frame(maxWidth: .infinity, maxHeight: .infinity)
            }.background(Color.white)
                .transparentNonAnimatingFullScreenCoverWithItem(item: $viewModel.notificationDetailsToShow, content: { details in
                    CustomPopup(content: NotificationDetailsPopUpView(notifyDetails: $viewModel.notificationDetailsToShow)){}
                })
                .onAppear{
                    viewModel.shouldShowTabBar = true
                    viewModel.resetNavigation = false
                    
                    if(viewModel.selectedView == Tab.INIT){
                        viewModel.selectTabView(tab: viewModel.firstView)
                    }
                }
                .onReceive(NotificationCenter.default.publisher(for: Notification.Name("DidReceiveNotification"))) { notification in
                    if let userInfo = notification.userInfo{
                        viewModel.ReceivedNotificationHandle(notification: userInfo)
                    }
                }
                .onReceive(NotificationCenter.default.publisher(for: Notification.Name("DidTapOnNotification"))) { notification in
                    if let userInfo = notification.userInfo{
                        viewModel.onTapReceivedNotificationHanlde(notification: userInfo)
                    }
                }
                .onReceive(NotificationCenter.default.publisher(for: .appOpenedOnNotificationClick)) { notification in
                    if let userInfo = notification.userInfo{
                        viewModel.onTapReceivedNotificationHanlde(notification: userInfo)
                    }
                    viewModel.selectTabView(tab: Tab.HOME_VIEW)
                }
        }.environmentObject(viewModel)
            .environmentObject(networkMonitor)
            .navigationBarBackButtonHidden(true)
            .navigationBarHidden(true)
    }
    @ViewBuilder
    private func tabContentView() -> some View {
        switch viewModel.selectedView {
        case Tab.HOME_VIEW:
            HomeView().environmentObject(viewModel)
        default:
            EmptyView()
        }
    }

}

However, how can get app launched notification details in CustomTabBar View?

plase help me..

本文标签: