我有一个 maui .net7 iOS 应用程序,当应用程序不在前台时,我似乎无法使推送通知正常工作。 (请注意,我没有使用 Firebase。)
场景1 当应用程序位于前台时收到推送通知时,将在 appDelegate 的 ReceivedRemoteNotification 函数中接收通知。然后,我将通知信息放入本地数据库,并使用插件 Plugin.LocalNotification 显示本地通知;此通知正确显示,单击时应用程序将打开特定视图。
这里一切都好。
场景2 当应用程序在后台运行时,会发生与在前台时相同的情况。通知记录在数据库中,会显示本地通知,单击后会执行正确的操作。
但是,它ALSO显示另一个“默认”通知,单击时不执行任何操作。
我需要阻止显示此“默认”通知。在我的代码中,我没有调用代码来添加通知: UNUserNotificationCenter.Current.AddNotificationRequest(request, OnNotificationError);
场景3 当应用程序未运行并且收到通知时,应用程序会显示“默认”通知,单击时该通知不执行任何操作,并且该通知不会记录在我的数据库中。
我需要确保将通知添加到数据库的代码运行。当应用程序关闭时,它不需要打开特定的视图,因为应用程序将要求用户登录,但我确实需要应用程序在 GUI 中显示通知,以便他们仍然可以到达正确的视图。
在 mac iOS 模拟器上调试对我来说不起作用(根本没有出现通知),所以我一直在尝试使用 appcenter 分析 logUsage() 来确定哪些代码被命中。当应用程序在后台时,日志记录似乎没有发生,因此很难说 UNUserNotificationCenterDelegate 的 WillPresentNotification 和 DidReceiveNotificationResponse 代码是否被命中。好像不是。
AppDelegate.cs
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
UNUserNotificationCenter.Current.Delegate = new UserNotificationCenterDelegate(); //my custom class
// ... code to register to register for notifications and check permission - works, removed for example
}
[Export("application:didReceiveRemoteNotification:")]
public void ReceivedRemoteNotification(UIApplication application, NSDictionary notification)
{
//code to process notification, add to DB and display the local notification starts here.
//Runs correctly when app is in foreground
}
UserNotificationCenterDelegate.cs
public class UserNotificationCenterDelegate : UNUserNotificationCenterDelegate, IUNUserNotificationCenterDelegate
{
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
//attempted adding to DB here for when the application is not running, did not work. Not sure this code is ever hit
completionHandler(UNNotificationPresentationOptions.None); //this should tell the app not to show the default notification
}
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
//this should be hit when the default notification is clicked. Not sure this is ever hit
if (!response.IsDismissAction)
{
//run code to open the correct view
}
completionHandler();// Inform caller it has been handled
}
}
谁能告诉我:
非常感谢!
我发现了另一个微软文档中没有提到的功能:
[Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")]
public void DidReceiveRemoteNotification(UIApplication application, NSDictionary notification, Action<UIBackgroundFetchResult> completionHandler)
{
//code to write the notification to the DB and display the local notification
completionHandler(UIBackgroundFetchResult.NewData);
}
当您的应用程序在前台或后台运行时,系统会调用此方法。 告诉应用程序收到远程通知,表明有数据需要获取。 使用此方法来处理您的应用程序传入的远程通知。
参见苹果的文档: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application
这里还提到: https://github.com/dotnet/maui/issues/6259
现在,当应用程序未运行时,我可以将通知写入数据库并显示本地通知!
还显示默认通知;我仍然需要确定如何防止当应用程序在后台或未运行时出现此通知。
你可以尝试这个代码 -
public func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
/// add code before this comment to get notification data and update in database
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
completionHandler(.noData)
/// write your code after this comment to show local notification
}
这应该隐藏默认通知,以防应用程序处于后台或未打开
让我知道这是否适合您。很高兴能提供帮助:)