didReceiveRemoteNotification не вызывается в iOS 13.3, когда приложение находится в фоновом режиме

10

Я бью себя по голове. Я внедряю push-уведомления. Все работает нормально (push-уведомление получено, значок обновлен), но в iOS 13.3 приложение метода (_: didReceiveRemoteNotification: fetchCompletionHandler :) не вызывается, когда приложение находится в фоновом режиме. Если приложение находится на переднем плане или использует устройство iOS 12, вызывается метод. Я регистрируюсь для push-уведомлений следующим образом:

[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        });
    }
}];

Полезная нагрузка установлена ​​на следующее

{"aps": {
    "badge": 10,
    "alert": "test",
    "content-available": 1
}}

Я попытался добавить «Удаленные уведомления» и «Фоновая обработка» в качестве возможностей приложения во всех вариантах (только «Удаленные уведомления» / «Фоновая обработка», без каких-либо из этих возможностей, включающих оба) без каких-либо изменений. Я назначил делегата для UNUserNotificationCenter, но снова безуспешно. Я установил заголовки соответственно:

curl -v \
 -H 'apns-priority: 4' \
 -H 'apns-topic: xx.xxxxx.xxxx' \
 -H 'apns-push-type: alert' \
 -H 'Content-Type: application/json; charset=utf-8' \
 -d '{"aps": {"badge": 10,"alert": "test", "content-available":1}}' \
 --http2 \
 --cert pushcert.pem \
 https://api.sandbox.push.apple.com/3/device/1234567890

Из документов говорится, что этот метод вызывается, даже когда приложение находится в фоновом режиме:

Используйте этот метод для обработки входящих удаленных уведомлений для вашего приложения. В отличие от метода application: didReceiveRemoteNotification:, который вызывается только тогда, когда ваше приложение выполняется на переднем плане, система вызывает этот метод, когда ваше приложение работает на переднем или заднем плане.

Что мне здесь не хватает для iOS 13?

MartinW1985
источник
Проверьте , если вы используете этот метод: developer.apple.com/documentation/uikit/uiapplicationdelegate/...
1
См. Выше: все работает нормально (push-сообщение получено, значок обновлен), но в iOS 13.3 приложение метода (_: didReceiveRemoteNotification: fetchCompletionHandler :) не вызывается, когда приложение находится в фоновом режиме.
MartinW1985,
приложение (_: didReceiveRemoteNotification: fetchCompletionHandler :) будет вызываться при нажатии на баннер уведомления
Да, это правильно. Мой вопрос: почему он не вызывается, когда приложение находится в фоновом режиме. Насколько я понимаю, в документах так сказано.
MartinW1985,
Вы пытались реализовать application(_:didReceiveRemoteNotification:withCompletionHandler:)метод?
HardikS

Ответы:

2

Вы установили

"content-available": 1

у вас бэкэнд APS полезен?

Также необходимо убедиться, что вы включили фоновый режим в файле info.plist вашего приложения iOS.

<key>UIBackgroundModes</key>
<array>
    <string>processing</string>
    <string>remote-notification</string>
</array>
Чжан чжан
источник
@matt сообщение было случайно отправлено, прежде чем я наберу все ответы. Теперь это завершено с изменением стороны приложения.
Чжан Чжан
1
Да, я сделал. Вы можете видеть из моего запроса CURL в моем начальном посте. Я также добавил «content-available»: 1 и перепробовал все фоновые режимы (включены, отключены, варианты), но приложение (_: didReceiveRemoteNotification: fetchCompletionHandler :) не вызывается. Только если приложение активно.
MartinW1985,
<string> processing </ string> => это важная строка
Донг Май
@ZhangZhan: Вы когда-нибудь решали эту проблему? Я сталкиваюсь с той же проблемой, когда молчание / фоновые уведомления не принимаются, даже если ключ, доступный для содержимого, установлен правильно. На iOS 12 все работает нормально, но на iOS13 работают только звуковые / визуальные уведомления. Я знаю, что Apple требует, чтобы новый тип заголовка был включен в уведомление, но это уже обработано (мы используем SNS). Интересно, что это не работает в симуляторе с файлом apns с последней версией XCode.
что
2

Я трачу билет поддержки, чтобы получить ответ на эту проблему.

Оказывается, что документация не является на 100% «действительной» для iOS 13 по этой теме. Устройство решает, просыпаться или нет. Хотя в документации указано немного другое.

Предпочтительный способ реализации Apple в качестве расширения уведомлений. После этого вы должны адаптировать полезную нагрузку для включения «mutable-content».

Позже я спросил службу поддержки, должен ли я подать радар, и они ответили «да».

MartinW1985
источник
если вы предоставляете расширение уведомления, приложение разбудило?
Питер Лапису
0

Внедрите, didRegisterForRemoteNotificationsWithDeviceTokenа также didFailToRegisterForRemoteNotificationsWithErrorв делегате вашего приложения, чтобы проверить, если устройство имеет хорошее соединение с сервером APN Apple. Если это не так, перезапустите устройство и / или попробуйте установить соединение через другую сеть Wi-Fi и перезапустите приложение.

Ely
источник
0

Этот метод делегата: -

(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler

вызывается, когда мы нажимаем на уведомление для iOS 13 и приложение находится в фоновом режиме.

user13150044
источник
1
Да, но я искал способ получить полезную нагрузку без нажатия на уведомление.
MartinW1985,
0

Вам необходимо реализовать расширение содержимого уведомлений

Поскольку я использовал OneSignal и его установочный код, он отлично работал для меня https://documentation.onesignal.com/docs/ios-sdk-setup

не уверен, что биты OneSignal имеют значение, но все равно добавляю их

import UserNotifications
import OneSignal

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request;
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // 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.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

}
Питер Лапису
источник