SwiftUI 处理在终止状态下点击的推送通知

问题描述 投票:0回答:2

我有一个具有聊天功能的 SwiftUI 应用程序,它使用 Firebase 作为后端,并使用 Cloud Function 来侦听新的聊天消息并通知用户。当用户在相应的聊天室之一收到新的聊天消息时,云功能向登录用户的所有设备发送通知。为了导航,我创建了一个通知管理器,如果用户点击了通知,它可以帮助应用程序在应用程序的嵌套视图中导航。

一切正常,但是当用户在应用程序终止后点击通知时,导航不起作用。我猜这是因为在用户恢复之前导航被点击并且其属性被更改......?我试图寻找与 UIKit 相关的解决方案(因为我没有找到任何与 SwiftUI 相关的解决方案),但还没有找到合适的解决方案。

在我的 AppDelegate 中:

weak var notificationManager: NotificationManager?

用户点击通知:

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID from userNotificationCenter didReceive: \(messageID)")
        }
        
        print("*** NotificationInfo: \(userInfo) ***")
        let info = userInfo as NSDictionary
        guard let chatID = info.value(forKey: "chatID") as? String else { return } // retrieving the ChatID from notification payload
        
        
        // Navigate to the room of the chatID when chat notification is tapped
        
        
        notificationManager?.pageToNavigationTo = 1 // navigate to messages view
        notificationManager?.recievedNotificationFromChatID = chatID // navigate to correct chat
        
        
        completionHandler()
    }

生命周期:

@main
struct VitaliiApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    @StateObject var session = SessionStore()
    let notificationManager = NotificationManager()
    
    func setUpdNotificationManager() {
        appDelegate.notificationManager = notificationManager
    }
    
    var body: some Scene {
        WindowGroup {
            
            ContentView()
                .environmentObject(session)
                .environmentObject(notificationManager)
                .onAppear {
                    setUpdNotificationManager()
                }   
        }
       
        
    }
}

通知管理器:

class NotificationManager: ObservableObject {
    static let shared = NotificationManager()
    @Published var pageToNavigationTo : Int?
    @Published var recievedNotificationFromChatID: String?
}

ContentView 的 LightWeight 示例

struct ContentView: View {
    
    @State var selection: Int = 0
    @EnvironmentObject var session: SessionStore
    
    @State var activeChatID: String?
    
    let tabBarImageNames = ["person.3", "message", "person"]
    
    @EnvironmentObject private var notificationManager: NotificationManager
    

        
    var body: some View {
        
        ZStack {
            Color.black
                .ignoresSafeArea()
            
            VStack {
                
                ZStack {
                    
                    switch selection {
                    case 0:
                         NavigationView {
                            HomeView()
                        }                        
                    case 1:
                        NavigationView {
                            InboxMessagesView(user: session.userSession, activeChatID: $activeChatID)
                            
                        }
                        .accentColor(.white)
                   
                    default:
                        NavigationView {
                            ProfileView(session: session.userSession)
                        }
 
                    }
                    
                }
                
                Spacer()
                
                
                    HStack {
                        
                        ForEach(0..<3) { num in
                            Button {
                                selection = num
                            } label: {
                                Spacer()
                                
                                Image(systemName: tabBarImageNames[num])
                                    .padding(.top, 10)
                                    .font(.system(size: 20, weight: .medium))
                                    .foregroundColor(selection == num ? .red : .white.opacity(0.7))
                                Spacer()
                            }
                            
                        }
                        
                        
                    }
            }
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
        .onReceive(notificationManager.$pageToNavigationTo) {
            guard let notificationSelection = $0 else  { return }
            self.selection = notificationSelection // navigates to page InboxMessagesView
            
        }
        .onReceive(notificationManager.$recievedNotificationFromChatID) {
            guard $0 != nil else { return }
            
            self.activeChatID = $0 // navigates to the correct chat that is associated with the chatID when the user taps on a chat notification
            
        }

        
    }
    
}
swiftui push-notification unusernotificationcenter
2个回答
2
投票

好吧,我在 Swift 中发现了同样的问题,解决方案是将点击的通知的操作延迟一秒钟。感觉更像是一个黑客,我想确切地知道异步发生了什么,但它工作得很好。

解决方案如下:

 DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { // <- here!!
            self.notificationManager?.pageToNavigationTo = 1
            self.notificationManager?.recievedNotificationFromChatID = chatID
 }

0
投票

我最近面临同样的问题,看到你的解决方案有助于解决我的问题,因为你在

中有一个单身人士
class NotificationManager: ObservableObject {
    static let shared = NotificationManager()
...
}

与其延迟通知 1 秒(这可能会适得其反),不如在

AppDelegate
中使用单例(通知管理器可能尚未启动,这就是为什么延迟 1 秒可能会解决您的问题)

以某事结束

let notificationManager = self.notificationManager ?? NotificationManager.shared()
notificationManager.pageToNavigationTo = 1
notificationManager.recievedNotificationFromChatID = chatID

对我来说,做这样的事情就成功了!

© www.soinside.com 2019 - 2024. All rights reserved.