Xamarin Forms:我是否涵盖了iOS Push Notifications的基础?

时间:2019-05-17 14:29:55

标签: ios xamarin.forms push-notification

问题:在3种不同背景下的不同行为

好的,好的,在iOS中,关于“推送通知”似乎可以发生三种不同的情况:

  1. 当应用在前台 不是 时收到推送通知
    • 通知中心中出现了一些东西
    • 如果通过轻按通知打开应用 ,则会调用AppDelegate.DidReceiveRemoteNotification(...)AppDelegate.ReceivedRemoteNotification(...),显然取决于实现的是哪一个(??)。
    • 如果在未点击通知的情况下打开了应用程序,则仅调用AppDelegate.WillEnterForeground(...) ,而没有明确提及通知,并且没有其他发生确认已收到通知。
  2. 当应用 在前台时收到推送通知时,它会导致UNUserNotificationCenterDelegate(如果有)执行{{1} }。

方法:从所有上下文路由到一种方法

因此,要使用Push覆盖所有基础,我需要在UNUserNotificationCenterDelegate.WillPresentNotification(...)AppDelegate.DidReceiveRemoteNotification(...) / AppDelegate.ReceivedRemoteNotification(...)AppDelegate.WillEnterForeground(...)这三种方法中实现一些东西。

这里有一些存根来展示我对所有这些方法的理解。

首先,我创建了一个具有UNUserNotificationCenterDelegate .WillPresentNotification(...)静态成员的自定义UNUserNotificationCenterDelegate

Shared

第二,在该类中,我创建了一个可以在每种情况下都路由到的处理程序(同样,这只是出于调试目的的存根):

public class IncomingNotificationHandler : UNUserNotificationCenterDelegate
{
    public static IncomingNotificationHandler Shared = new IncomingNotificationHandler();

    ...
 }

第三,在同一个类中,我实现了 //sets all parameters to null by default, so it can be called from methods //that don't know anything about notifications: public void HandleNotificationsIfAny(UIApplication application = null, NSDictionary userInfo = null, Action<UIBackgroundFetchResult> completionHandler = null) { //checks if userInfo is null, and logs its conclusions about that: if (userInfo == null) { //In the null case, we can get pending notifications from //UNUserNotificationCenter: UNNotification[] pendingNotifications = new UNNotification[] { }; UNUserNotificationCenter.Current.GetDeliveredNotifications(returnedValue => pendingNotifications = returnedValue); //Then we log the number of pending notifications: Debug.WriteLine("IncomingNotificationHandler: HandleNotificationsIfAny(...): delivered notification count: " + pendingNotifications.Length); //And make note of where this was probably called from: Debug.WriteLine("IncomingNotificationHandler: HandleNotificationsIfAny(...): may have been called from this.WillPresentNotification(...) OR AppDelegate.WillEnterForeground(...)"); return; }); } else { //In the non-null case, we log the userInfo Debug.WriteLine("IncomingNotificationHandler: HandleNotificationsIfAny(...): just got info: " + userInfo); //And make note of where this was probably called from: Debug.WriteLine("IncomingNotificationHandler: HandleNotificationsIfAny(...): may have been called from AppDelegate.DidReceiveRemoteNotification(...)"); } } 所需的单个方法,并从中路由到处理程序:

UNUserNotificationCenterDelegate

最后,在 public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler) { HandleNotificationsIfAny(); } 内,我从两种相关方法路由到同一处理程序:

AppDelegate

就此而言,无论我的应用如何收到警报,甚至根本没有收到警报,我都以相同的方式处理通知事件。

有人知道我现在是否已经承保它,或者是否还有其他需要处理的情况?

1 个答案:

答案 0 :(得分:0)

对于第一种情况:AppDelegate.ReceivedRemoteNotification

它反映了客观的c方法:application:didReceiveRemoteNotification:,但是自iOS 10:https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623117-application?language=objc起,不推荐使用此事件。因此,我认为无需处理此事件。

第二种情况:AppDelegate.DidReceiveRemoteNotification

如果您尚未实现UNUserNotificationCenter,现在仍可以利用它来处理通知,请注意,它仅在iOS 7+之后才有效。此外,此事件将在应用程序位于前台时触发,如果您的应用程序位于后台,则仅当用户单击通知以打开您的应用程序时才会触发此事件。如果用户单击该图标打开应用程序,则无法访问通知的信息。

我认为处理AppDelegate.WillEnterForeground不是一个好方法,因为即使没有通知,每次应用程序从后台恢复到前台时都会调用它。

对于这种情况:UNUserNotificationCenterDelegate

您只能在iOS 10之后使用此功能。在设备iOS 10+上实现该功能后,将永远不会触发DidReceiveRemoteNotificationReceivedRemoteNotification。当应用程序位于前台时,将调用WillPresentNotification。当应用程序在后台运行并且用户单击通知以将其打开时,将触发DidReceiveNotificationResponse

结论是,如果您想轻松处理通知AppDelegate.DidReceiveRemoteNotification就足够了。如果要使用UNUserNotificationCenter的新功能,则应同时使用AppDelegate.DidReceiveRemoteNotificationUNUserNotificationCenter。前一个用于iOS 7+设备,后一个用于iOS 10+设备。

更新

对于iOS 10或更高版本,您可以使用UNUserNotificationCenter.Current.GetDeliveredNotifications来获取仍显示在通知中心中的通知。并且,如果您只想支持iOS版本10及更高版本。我认为UNUserNotificationCenter就足够了,不需要实现AppDelegate.DidReceiveRemoteNotification(...)AppDelegate.ReceivedRemoteNotification(...)

  • 如果应用处于后台/已终止状态,并且用户单击了以下通知: 打开应用程序,将调用DidReceiveNotificationResponse。
  • 如果 用户单击图标打开您的应用程序,并且该应用程序被杀,您应该 将您的逻辑代码放在FinishedLaunching中。
  • 如果用户单击图标 打开您的应用程序并且该应用程序在后台运行,您可以处理 WillEnterForeground与以前一样。
  • 如果应用在前台运行, 处理WillPresentNotification