didReceiveRemoteNotification no se llama en iOS 13.3 cuando la aplicación está en segundo plano

10

Me estoy golpeando la cabeza. Estoy implementando notificaciones push. Todo funciona bien (se recibe el envío, se actualiza la insignia) pero en iOS 13.3 la aplicación del método (_: didReceiveRemoteNotification: fetchCompletionHandler :) no se llama cuando la aplicación está en segundo plano. Si la aplicación está en primer plano o usa un dispositivo iOS 12, se llama al método. Me registro para la notificación push de la siguiente manera:

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

La carga útil se establece en lo siguiente

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

Intenté agregar "Notificaciones remotas" y "Procesamiento en segundo plano" como capacidades de la aplicación en todas las variaciones (solo "Notificaciones remotas" / "Procesamiento en segundo plano", sin ninguna de esas capacidades, permitiendo ambas) sin ningún cambio. Configuré el delegado para UNUserNotificationCenter pero nuevamente sin éxito. Configuré los encabezados en consecuencia:

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

En los documentos, se indica que se llama a este método incluso cuando la aplicación está en segundo plano:

Use este método para procesar notificaciones remotas entrantes para su aplicación. A diferencia de la aplicación: didReceiveRemoteNotification: método, que se llama solo cuando su aplicación se ejecuta en primer plano, el sistema llama a este método cuando su aplicación se ejecuta en primer plano o en segundo plano.

¿Qué me estoy perdiendo aquí para iOS 13?

MartinW1985
fuente
Compruebe si está utilizando este método: developer.apple.com/documentation/uikit/uiapplicationdelegate/…
1
Consulte más arriba: todo funciona bien (se recibe el envío, se actualiza la insignia) pero en iOS 13.3 la aplicación del método (_: didReceiveRemoteNotification: fetchCompletionHandler :) no se llama cuando la aplicación está en segundo plano.
MartinW1985
Se llamará a la aplicación (_: didReceiveRemoteNotification: fetchCompletionHandler :) cuando toque el banner de notificación
Si eso es correcto. Mi pregunta es: ¿Por qué no se llama cuando la aplicación está en segundo plano? Según tengo entendido, los documentos lo dicen.
MartinW1985
¿Has probado implementando el application(_:didReceiveRemoteNotification:withCompletionHandler:)método?
HardikS

Respuestas:

2

Has puesto

"content-available": 1

en su carga útil de back-end APS?

También debe asegurarse de haber habilitado el modo de fondo en el archivo info.plist de su aplicación iOS

<key>UIBackgroundModes</key>
<array>
    <string>processing</string>
    <string>remote-notification</string>
</array>
Zhang Zhan
fuente
@matt la publicación se envió accidentalmente antes de escribir todas las respuestas. Ahora se completa con el cambio lateral de la aplicación.
Zhang Zhan
1
Sí, lo hice. Puedes verlo desde mi solicitud CURL en mi publicación inicial. También agregué "content-available": 1 y probé todos los modos de fondo (habilitado, deshabilitado, variaciones) pero aún no se llama a la aplicación (_: didReceiveRemoteNotification: fetchCompletionHandler :). Solo si la aplicación está activa.
MartinW1985
<string> procesando </string> => esta es una línea importante
Dong Mai
@ZhangZhan: ¿Alguna vez resolviste este problema? Me encuentro con el mismo problema donde no se reciben notificaciones silenciosas / en segundo plano, incluso cuando la clave de contenido disponible está configurada correctamente. En iOS 12, todo funciona correctamente, pero en iOS13, solo funcionan las notificaciones audibles / visuales. Soy consciente de que Apple requiere que se incluya un nuevo tipo de encabezado en la notificación, pero eso ya se maneja (estamos usando SNS). Curiosamente, esto no funciona en el simulador con el archivo apns con la última versión de XCode.
lo que
2

Gasto un ticket de soporte para obtener una respuesta a este problema.

Resulta que la documentación no es 100% "válida" para iOS 13 sobre este tema. El dispositivo decide si despertarse o no. Aunque la documentación establece un poco diferente.

La forma preferida de implementación de Apple como una extensión de notificación. Después de eso, debe adaptar la carga útil para incluir "contenido mutable".

Luego le pregunté al soporte si debía archivar un radar y me respondieron "sí".

MartinW1985
fuente
si proporciona una extensión de notificación, ¿se activa la aplicación?
Peter Lapisu
0

Implemente didRegisterForRemoteNotificationsWithDeviceTokeny también didFailToRegisterForRemoteNotificationsWithErroren el delegado de su aplicación, para verificar si el dispositivo se conecta bien con el servidor APN de Apple. Si este no es el caso, reinicie el dispositivo y / o intente establecer una conexión a través de otra red Wi-Fi y reinicie la aplicación.

Ely
fuente
0

Este método delegado: -

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

se invoca cuando hacemos clic en la notificación para iOS 13 y la aplicación está en segundo plano.

usuario13150044
fuente
1
Sí, pero estaba buscando una forma de obtener la carga útil sin hacer clic en la notificación.
MartinW1985
0

Debe implementar una extensión de contenido de notificación

Como estaba usando OneSignal y su código de configuración, esto funcionó bien para mí https://documentation.onesignal.com/docs/ios-sdk-setup

no estoy seguro si los bits de OneSignal hacen la diferencia, pero anexándolos de todos modos

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)
        }
    }

}
Peter Lapisu
fuente