5

最近まで (iOS 12 リリースより前だと思います)、通知センターからのリモート プッシュ通知の削除は、removeDeliveredNotifications.

突然、通知サービス拡張機能のコードを変更しなければ、通知が削除されなくなりました。

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {

    self.contentHandler = contentHandler
    self.content = request.content.mutableCopy() as? UNMutableNotificationContent

    guard let content = content else {
        contentHandler(request.content)
        return
    }

    UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
        let matchingNotifications = notifications.filter({ $0.request.content.threadIdentifier == "myThread" && $0.request.content.categoryIdentifier == "myCategory" })
        UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: matchingNotifications.map({ $0.request.identifier }))
        contentHandler(content)
    }
}

関数は、通知を削除せずに完了します。実際のデバイスでデバッグするmatchingNotificationsと、通知が含まれていることが示され、削除する通知 ID が正しく提供されます。

テストでは、呼び出しがremoveAllDeliveredNotifications()機能し、すべての通知が削除されます。

上記の関数はoverride func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)

ここで何が問題なのですか?

4

1 に答える 1

5

私は@KymercontentHandlerによる提案を試し、しばらく待ってから(たとえば3秒)電話をかけると問題が解決したことを確認しました。

// UNUserNotificationCenter *notificationCenter
// NSArray(NSString *) *matchingIdentifiers;
// UNNotificationContent *content;
if (matchingIdentifiers.count > 0) {
    NSLog(@"NotificationService: Matching notification identifiers to remove: %@.", matchingIdentifiers);               
    [notificationCenter removeDeliveredNotificationsWithIdentifiers:matchingIdentifiers];

    // Note: dispatch delay is in nanoseconds... :(
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3000000000), dispatch_get_main_queue(), ^{
        NSLog(@"Replacing content after 3 seconds.");
        self.contentHandler(content);
    });
}

したがって、これはタイミングの問題であることを意味していると思います。iOScontentHandlerは が呼び出された後にプロセスを積極的にフリーズし、notificationCenter

編集: 質問はそれに対処する方法に関するものではありませんでしたが、コメント セクションは恣意的な時間の遅延について懸念をもたらしました。私のテストでは、コールバックを別のループに投稿するだけで十分でした。

dispatch_async(dispatch_get_main_queue(), ^{
    contentHandler(content);
});
于 2019-06-18T22:37:07.407 に答える