Actualizar la insignia con notificación push mientras la aplicación está en segundo plano

82

Tengo una notificación de inserción funcionando y logré actualizar el recuento de insignias del icono cuando la aplicación se pone en primer plano.

Sin embargo, estoy un poco confundido acerca de esto ... el iPhone recibe la notificación y aparece el mensaje emergente para activar mi aplicación, y la insignia solo se actualiza después de que inicie la aplicación.

Esto no suena bien en términos de experiencia de usuario. Tengo entendido que el conteo de insignias debe notificar al usuario lo que necesita acción, a través de un conteo incrementado, pero esto no sucede hasta una etapa posterior cuando la aplicación está activa.

Entonces, ¿hay alguna manera de decirle a la aplicación que actualice su recuento de insignias cuando recibe notificaciones automáticas y mientras está en segundo plano?

Tenga en cuenta que mi aplicación no utiliza la ubicación y que tengo UIRemoteNotificationTypeBadgeen la solicitud de registro de notificación.

Saludos AF

Abolfoooud
fuente
¿Quieres mostrar la insignia en el icono de la aplicación?
Aman Aggarwal
Estoy mostrando el recuento en pestañas. Y enfrentando el mismo problema. Cuando la aplicación está en segundo plano, el recuento no aumenta. ¿Cómo puedo configurar?
Srusti Thakkar

Respuestas:

79

Dado que las notificaciones push son manejadas por iOS y no su aplicación, no puede cambiar la insignia de la aplicación al recibir una notificación push.

Pero puede enviar el número de placa en la carga útil de la notificación push, pero tendrá que hacer el cálculo del lado del servidor.

Debería leer la Guía de programación de notificaciones push y locales y especialmente la Carga útil de notificaciones .

La carga útil podría verse así:

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9
    }
}

Ahora el icono de la insignia de la aplicación de la aplicación mostrará 9.

rckoenes
fuente
4
Ya estoy haciendo eso ... pero este valor se recupera solo cuando mi aplicación se pone en primer plano, que luego uso para actualizar el valor de la insignia usando [UIApplication sharedApplication] .applicationIconBadgeNumber = count;
Abolfoooud
7
No, es necesario establecer el número de placa en la carga útil de notificaciones push.
rckoenes
11
Eché otro vistazo a mi estructura de carga útil y parece que estaba pasando el valor del parámetro de la insignia como una cadena '4' en lugar de un int 4 !!! Ahora lo tengo funcionando ... gracias por la ayuda
Abolfoooud
Probé que no funciona cuando se cambia la insignia de estructura de carga útil
wod
1
@wod ¿a qué te refieres con: cambio en la insignia de estructura de carga útil?
rckoenes
11

Podemos modificar el número de placa cuando estamos en segundo plano enviando el parámetro "placa" en el paquete de notificaciones push. Como señaló @rckoenes, el JSONparámetro para la insignia debe ser un INTEGER .

Ejemplo de código PHP para hacer lo mismo

// Create the payload body
$body['aps'] = array(
        'alert' => $message,
        'badge' => 1,
        'sound' => 'default'
        );

badge => 1 donde 1 es un número entero, no una cadena (es decir, sin apóstrofos)

prajul
fuente
11

En realidad, en iOS 10, una notificación remota llamará automáticamente didReceiveRemoteNotification método en su AppDelegate.

Tiene 2 formas de actualizar el recuento de insignias en segundo plano.
También hice esto para mi aplicación actual. Tampoco necesita una extensión del servicio de notificación.

1er camino:

Envíe la clave de la tarjeta APS con su carga útil a APN.
Esto actualizará el recuento de insignias de acuerdo con su valor entero en su carga útil de insignias. ex:

// Payload for remote Notification to APN
{
    "aps": {
        "content-available": 1,
        "alert": "Hallo, this is a Test.",
        "badge": 2, // This is your Int which will appear as badge number,
        "sound": default
    }
}

2do camino:

Puede cambiar su application.applicationState y actualizar sus insignias Count cuando el applicationState está en .background. PERO debe tener cuidado de no establecer el parámetro de clave de la insignia en su carga útil de notificación cuando envíe a APN ex

// Payload to APN as silent push notification
{
    "aps": {
        "content-available": 1
    }
}

Maneje la actualización de la insignia de acuerdo con el estado de la aplicación:

Aquí está mi código de trabajo para la actualización del número de credenciales sin clave de credencial en la carga útil de APN.

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    print("APN recieved")
    // print(userInfo)
    
    let state = application.applicationState
    switch state {
        
    case .inactive:
        print("Inactive")
        
    case .background:
        print("Background")
        // update badge count here
        application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1
        
    case .active:
        print("Active")

    }
}

Restablecer el recuento de credenciales:

No olvide restablecer el recuento de insignias cuando su aplicación vuelva al estado activo.

func applicationDidBecomeActive(_ application: UIApplication) {
    // reset badge count
    application.applicationIconBadgeNumber = 0
}
Gkiokan
fuente
¿Cómo se actualiza la insignia si la aplicación no se ejecuta en segundo plano?
Nagendra Rao
1
Si envía el APS con la clave de contenido disponible, se ejecutará el método didReceiveRemoteNotification independientemente del estado de la aplicación. Pruébelo con un dispositivo nativo. Si tiene iOS, puede usar esta herramienta para enviar su objeto JSON a APN: github.com/noodlewerk/NWPusher
Gkiokan
guau, genial, ¿y si envío una notificación sin contenido disponible? (que se trata de cualquier notificación sin antecedentes). didReceiveRemoteNotificationno se llama
StackExploded
6
    **This is the APNS payload get back from server.**

    {
        "aps" : {
            "alert" : "You got your emails.",
            "badge" : 9,
            "sound" : "bingbong.aiff"
        },
        "acme1" : "bar",
        "acme2" : 42
    }

El valor de la insignia clave se considera automáticamente como el recuento de la insignia. En el lado de la aplicación ios no es necesario calcular o manejar el recuento. En el ejemplo anterior 9 es el recuento de insignias, por lo que el ícono de su aplicación mostrará 9.

NOTA Mientras su aplicación está cerrada, no puede manejar las credenciales por su cuenta. Es por eso que usamos la clave de credencial de APNS Payload Para una mejor aclaración sobre la notificación, consulte la documentación

Si desea reducir el recuento de insignias por su cuenta, disminuya el recuento y actualícelo usted mismo. de la siguiente manera

Prabhat Pandey
fuente
4

Si está utilizando NotificationServiceExtension, puede actualizar la insignia en eso.

var bestAttemptContent : UNMutableNotificationContent? // 
bestAttemptContent.badge = 0//any no you wanna display

Cada vez que tu aplicación reciba una notificación, se llamará a tu extensión de servicio. Guarda ese valor en el valor predeterminado del usuario y muéstralo. Para compartir los valores predeterminados del usuario entre la aplicación y la extensión, debe habilitar el grupo de aplicaciones en la aplicación. Leer más aquí

Surjeet Rajput
fuente
puede guardar ese recuento de notificaciones en el servidor y enviarlo con una notificación.
Surjeet Rajput
Utilizo Firebase Cloud Messaging, ¿sabes cómo puedo hacerlo?
Ghiggz Pikkoro
1

Para Firebase Cloud Messaging (FCM) debería ser así:

{
  "to": "some_token",

  "notification": {
    "body": "this is a body",
    "title": "this is a title",
    "badge" : 1
  }, 

  "priority": "high", 
}
Александр Бабич
fuente
0
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    application.applicationIconBadgeNumber = 0;
    NSLog(@"userInfo %@",userInfo);

    for (id key in userInfo) {
        NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
    }

    [application setApplicationIconBadgeNumber:[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]];
    NSLog(@"Badge %d",[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]);
}
suvi
fuente
¿Por qué está utilizando intValue en lugar de integerValue, que es un NSInteger? @property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
Alex Zavatone
0

Como dijo @rckoenes, tendrá que hacer el cálculo del lado del servidor, pero ¿cómo podría saber cuándo aumentar el valor del número de placa que debe enviar en la carga útil?

Cuando inicie la aplicación, enviará un mensaje a su servidor indicando que la aplicación se ha iniciado. Por lo tanto, en el lado del servidor, comienza de nuevo desde la insignia = 0, y si bien el servidor no recibe mensajes, aumente el número de la insignia con cada carga útil de notificación automática.

Mustafa
fuente
0

en la carga útil de apns, debe definir "contenido disponible": 1 para actualizar el recuento de insignias en modo de fondo

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {


// increase badge count, but no need if you include content-available

application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1

}

func applicationDidBecomeActive(_ application: UIApplication) {

// reset badge count

application.applicationIconBadgeNumber = 0

}

por ej.

"aps":{
    "alert":"Test",
    "sound":"default",
    "content-available":1

}
Prashant Kumar
fuente
el propósito de content-available = 1 es notificación silenciosa, no para credencial.
Manish
0

en el legado, su trabajo, "insignia" cuenta

{
  "to": "token",
  "notification": {
    "title": "Example",
    "body": "Tiene 22 actualizaciones.",
    "badge":278
  },
  "data": {
    "story_id": "story_12345",
    "count_vaca":22
  }
}
Javier J Solis Flores
fuente
-1

Después de recibir una notificación remota cuando abre la aplicación,

Obtenga el número de insignia actual en " didBecomeActive" Método de su AppDelegate.

Archivo usando el siguiente código:

int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badgeCount = badgeCount + 1;
Ved Gupta
fuente
3
Eso no funcionará hasta que el usuario toque la aplicación o la notificación para iniciar la aplicación. No hará lo que quiere el OP, actualizar la insignia cuando la aplicación está en segundo plano y antes de que el usuario haya interactuado con la aplicación o la notificación.
Alex Zavatone