Xamarin — iOS: Почему я не получаю push-уведомления с приложением на переднем плане через NotificationServiceExtension?

#xamarin #xamarin.ios #apple-push-notifications #unnotificationserviceextension

Вопрос:

Push-уведомления, которые проходят через расширение, всегда поступают, когда приложение убито, я могу заметить, что на устройстве e просматриваются журналы, напечатанные расширением. Когда приложение находится на переднем плане, ничего не происходит, и я не вижу журналов в расширении или в методе WillPresentNotification в AppDelegate (метод, который отлично работает на переднем плане с «обычным» нажатием, которое не нужно перехватывать расширением). Я также попытался добавить метод ReceivedRemoteNotification(…), ни один из этих методов не был вызван, как я видел из журналов.

Я использую UNNotificationServiceExtension для отображения содержимого уведомления.

 [Register("NotificationService")]

public class NotificationService : UNNotificationServiceExtension
{
    Action<UNNotificationContent> ContentHandler { get; set; }
    UNMutableNotificationContent BestAttemptContent { get; set; }

    .
    .
    .

    protected NotificationService(IntPtr handle) : base(handle)
    {
        // Note: this .ctor should not contain any initialization logic.
    }

    public override void DidReceiveNotificationRequest(UNNotificationRequest request,
                                                       Action<UNNotificationContent> contentHandler)
    {
        Console.WriteLine("NOTIFICATIONS: NotificationExtension: entered DidReceive");

        ContentHandler = contentHandler;
        BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();

        // Mapping of body and title

        ContentHandler(BestAttemptContent);
    }


    public override void TimeWillExpire()
    {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.

        Console.WriteLine("NOTIFICATIONS: NotificationExtension: entered TimeWillExpire");

        ContentHandler(BestAttemptContent);
    }
}
 

В AppDelegate у меня есть код для отображения уведомления на переднем плане:

 [Register("AppDelegate")]
public partial class AppDelegate : FormsApplicationDelegate,
                                   IUNUserNotificationCenterDelegate,
                                   IUIAlertViewDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary launchOptions)
    {
        LogBroker.Instance.TraceDebug("START");
        
        .
        .
        .
        
        LogBroker.Instance.TraceDebug("RegisterForNotifications: Register For Push Notification");
        UNUserNotificationCenter.Current.RequestAuthorization(
            UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
            (approved, err) => {

                if (err != null)
                {
                    LogBroker.Instance.TraceError($"RegisterForNotifications: {err.LocalizedDescription}");
                    return;
                }

                if (approved)
                {
                    InvokeOnMainThread(() =>
                    {
                        LogBroker.Instance.TraceDebug("RegisterForNotifications: Approved");
                        UIApplication.SharedApplication.RegisterForRemoteNotifications();
                    });
                }
                else
                {
                    LogBroker.Instance.TraceWarning($"RegisterForNotifications: Rejected by user!");
                }

            });

        UNUserNotificationCenter.Current.Delegate = this;

        LoadApplication(new App());
        
        return base.FinishedLaunching(app, launchOptions);
    }

    .
    .
    .

    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter _, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        LogBroker.Instance.TraceDebug($"NOTIFICATIONS: entered WillPresentNotification");

        var pushType = notification.Request.Content.UserInfo?.ValueForKey(new NSString("push-type"))?
                                   .ToString() ?? "";

        LogBroker.Instance.TraceDebug($"NOTIFICATIONS: push type - {pushType}");

        if (pushType == "call")
        {
            completionHandler(UNNotificationPresentationOptions.None);
        }
        else
        {
            LogBroker.Instance.TraceDebug($"NOTIFICATIONS: show push notification");
            completionHandler(UNNotificationPresentationOptions.Alert |
                              UNNotificationPresentationOptions.Sound);
        }
    }
}
 

Полезная нагрузка уведомлений выглядит примерно так:

 {
aps =     {
    alert =         {
        "loc-args" =             (
            "***"
        );
        "loc-key" = "IM_MSG";
    };
    badge = 1;
    "mutable-content" = 1;
    sound = "msg.caf";
};
"call-id" = 909d32775168c0db;
"domain-name" = "***";
panda = blue;
"pn_ttl" = 30;
"push-services" = vdes;
"push-type" = message;
"text-message" = "DND;ON";
 

}

Комментарии:

1. Попробуйте добавить » «изменяемое содержимое»=1» в aps={….}

2. Спасибо, Адрейн, но это еще не все

3. Вы запрашивали разрешение на уведомление?

4. Да, и одобрено пользователем

5. Как насчет настройки plist? Вы создали расширение службы уведомлений?