recuperar - Notificación push de iOS: ¿cómo detectar si el usuario tocó la notificación cuando la aplicación está en segundo plano?
recuperar notificaciones iphone (10)
Hay muchos hilos de stackoverflow con respecto a este tema, pero todavía no encontré una buena solución.
Si la aplicación no está en segundo plano, puedo verificar
launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]
en la
application:didFinishLaunchingWithOptions:
llame para ver si se abrió desde una notificación.
Si la aplicación está en segundo plano, todas las publicaciones sugieren usar la
application:didReceiveRemoteNotification:
y verificar el estado de la aplicación.
Pero como experimenté (y también como sugiere el nombre de esta API), se llama a este método cuando se recibe la notificación, en lugar de tocarlo.
Entonces, el problema es que si la aplicación se inicia y luego se
application:didReceiveNotification
segundo plano, y usted sabe que se recibió una notificación de la
application:didReceiveNotification
(
application:didFinishLaunchWithOptions:
no se activará en este punto), ¿cómo sabe si el usuario reanudó la aplicación? tocando la notificación o simplemente tocando el ícono de la aplicación?
Porque si el usuario tocó la notificación, la expectativa es abrir la página mencionada en esa notificación.
De lo contrario no debería.
Podría usar
handleActionWithIdentifier
para notificaciones de acciones personalizadas, pero esto solo se activa cuando se toca un botón de acción personalizada, no cuando el usuario toca el cuerpo principal de la notificación.
Gracias.
EDITAR:
Después de leer una respuesta a continuación, pensé de esta manera que puedo aclarar mi pregunta:
¿Cómo podemos diferenciar estos 2 escenarios?
(A) 1.app va al fondo; 2. notificación recibida; 3. toques de usuario en la notificación; 4. la aplicación entra en primer plano
(B) 1.app va al fondo; 2. notificación recibida; 3. el usuario ignora la notificación y toca el ícono de la aplicación más tarde; 4. la aplicación entra en primer plano
Desde la
application:didReceiveRemoteNotification:
se activa en ambos casos en el paso 2.
O, ¿debería la
application:didReceiveRemoteNotification:
en el paso 3 solo para (A), pero de alguna manera configuré mi aplicación de manera incorrecta, así que la veo en el paso 2?
En mi caso, el modo de fondo desactivado no hizo ninguna diferencia. Sin embargo, cuando se suspendió la aplicación y el usuario tocó la notificación, pude manejar el caso en este método de devolución de llamada:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
}
Hay dos funciones para manejar la Notificación de inserción recibida en el interior:
class PushNotificationManager: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate{
}
Cuando probé el primer disparador tan pronto como llegó la notificación
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(UNNotificationPresentationOptions.alert)
//OnReceive Notification
let userInfo = notification.request.content.userInfo
for key in userInfo.keys {
Constants.setPrint("/(key): /(userInfo[key])")
}
completionHandler([])
}
Y el segundo cuando se toca en la notificación:
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//OnTap Notification
let userInfo = response.notification.request.content.userInfo
for key in userInfo.keys {
Constants.setPrint("/(key): /(userInfo[key])")
}
completionHandler()
}
También lo probé con el estado activado / desactivado de notificación remota (en modos de fondo).
He estado buscando lo mismo que usted y de hecho encontré una solución que no requiere notificación remota para marcar.
Para verificar si el usuario ha tocado, si la aplicación está en segundo plano o está activa, solo tiene que verificar el estado de la aplicación en
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateActive) {
//app is currently active, can update badges count here
}else if(application.applicationState == UIApplicationStateBackground){
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
}else if(application.applicationState == UIApplicationStateInactive){
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
}
Para más información consultar:
Referencia del marco UIKit> Referencia de clase UIApplication> UIApplicationState
OK, finalmente lo descubrí.
En la configuración de destino tab pestaña Capacidades ➝ Modos de fondo, si
application:didReceiveRemoteNotification:
"Notificaciones remotas", la
application:didReceiveRemoteNotification:
se activará tan pronto como llegue la notificación (siempre que la aplicación esté en segundo plano), y en ese caso no hay manera de saber si el usuario tocará la notificación.
Si desmarca esa casilla, la
application:didReceiveRemoteNotification:
se activará solo cuando toque la notificación.
Es un poco extraño que marcar esta casilla cambie la forma en que se comporta uno de los métodos delegados de la aplicación. Sería mejor si esa casilla está marcada, Apple usa dos métodos de delegado diferentes para la recepción de notificaciones y el toque de notificaciones. Creo que la mayoría de los desarrolladores siempre quieren saber si se toca una notificación o no.
Esperemos que esto sea útil para cualquier otra persona que se encuentre con este problema. Apple tampoco lo documentó claramente here así que me llevó un tiempo darme cuenta.
Para iOS 10 y superior, coloque esto en AppDelegate, para conocer la notificación se toca (funciona, incluso la aplicación está cerrada o abierta)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
print("notification tapped here")
}
Puede configurar la carga útil de su notificación push para llamar a la aplicación del delegado de la
application:didReceiveRemoteNotification:fetchCompletionHandler:
método cuando la aplicación está en segundo plano.
Puede establecer algún indicador aquí para que cuando el usuario inicie su aplicación la próxima vez, pueda realizar su operación.
De la documentación de Apple, debe usar estos métodos para descargar contenido nuevo asociado con notificaciones push.
También para que esto funcione, debe habilitar la notificación remota desde los modos en segundo plano y su carga útil de notificaciones push debe contener
content-available
clave de
content-available
con su valor establecido en 1. Para obtener más información, consulte Uso de notificaciones push para iniciar una sección de descarga desde el documento de Apple
developer.apple.com/library/ios/documentation/iPhone/Conceptual/…
.
Otra forma es tener un recuento de insignias en la carga útil de notificaciones push. Entonces, la próxima vez que inicie su aplicación, puede verificar el recuento de credenciales de la aplicación. Si es mayor que cero, realice su operación y recuento de insignias cero / claro del servidor también.
Espero que esto te ayude.
Según iOS / XCode: ¿cómo saber que la aplicación se ha lanzado con un clic en la notificación o en el icono de la aplicación de trampolín? debe verificar el estado de la aplicación en didReceiveLocalNotification de esta manera:
if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
{
// user has tapped notification
}
else
{
// user opened app from app icon
}
Aunque no tiene sentido para mí, parece funcionar.
Si alguien lo quiere en Swift 3.0
switch application.applicationState {
case .active:
//app is currently active, can update badges count here
break
case .inactive:
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
break
case .background:
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
break
default:
break
}
para swift 4
switch UIApplication.shared.applicationState {
case .active:
//app is currently active, can update badges count here
break
case .inactive:
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
break
case .background:
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
break
default:
break
}
Si tiene "Modos de fondo"> "Notificaciones remotas" marcadas == SÍ, toque en el evento de notificación que llegará a:
-(void)userNotificationCenter:(UNUserNotificationCenter *)center **didReceiveNotificationResponse**:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler.
Me ayudó. Por favor, disfruta :)
También me encontré con este problema, pero en iOS 11 con el nuevo Marco de
UserNotifications
.
Aquí para mí es así:
-
Nuevo lanzamiento:
application:didFinishLaunchingWithOptions:
-
Recibido en primer plano:
application:didReceiveRemoteNotification:fetchCompletionHandler:
-
Recibido en segundo plano:
userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: