¿Mostrar un banner de notificación de iOS stock cuando su aplicación está abierta y en primer plano?

Cuando la aplicación oficial iOS Messages de Apple está abierta y en primer plano, los mensajes nuevos de otros contactos desencadenan un stock, un banner de alerta de notificación nativo de iOS. Ver la imagen a continuación.

¿Es esto posible en aplicaciones de terceros en App Store? Notificaciones locales y / o automáticas para su aplicación mientras su aplicación está abierta y en primer plano .

Al probar mi aplicación , se reciben notificaciones pero no se muestra ninguna IU de alerta de iOS .

Pero este comportamiento se ve en la aplicación de mensajes oficial de Apple:

Los mensajes están abiertos y en primer plano. Aún muestra una alerta de notificación.

La Guía de progtwigción de notificación local y remota dice:

Cuando el sistema operativo entrega una notificación local o notificación remota y la aplicación de destino no se ejecuta en primer plano , puede presentar la notificación al usuario a través de una alerta , número de distintivo de icono o sonido.

Si la aplicación se ejecuta en primer plano cuando se entrega la notificación, el delegado de la aplicación recibe una notificación local o remota.

Entonces, sí, podemos recibir los datos de notificación en primer plano. Pero no veo forma de presentar la IU de alerta de notificación nativa de iOS .

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // I know we still receive the notification `userInfo` payload in the foreground. // This question is about displaying the stock iOS notification alert UI. // Yes, one *could* use a 3rd party toast alert framework. [self use3rdPartyToastAlertFrameworkFromGithub] } 

¿Está usando Messages entonces una API privada para mostrar la alerta en primer plano?

A los fines de esta pregunta, no sugiera ninguna alerta emergente de “brindis de terceros en github, etc. Solo estoy interesado si esto se puede hacer utilizando la IU de acciones local iOS o alertas de notificación de inserción mientras su aplicación es abierto y en primer plano .

iOS 10 agrega el protocolo UNUserNotificationCenterDelegate para el manejo de notificaciones mientras su aplicación está en primer plano.

El protocolo UNUserNotificationCenterDelegate define métodos para recibir notificaciones y para manejar acciones. Cuando su aplicación está en primer plano, las notificaciones que llegan se entregan a su objeto delegado en lugar de mostrarse automáticamente mediante las interfaces del sistema.

Rápido:

 optional func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) 

C objective:

 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler; 

Los indicadores UNNotificationPresentationOptions le permiten especificar UNNotificationPresentationOptionAlert para mostrar una alerta utilizando el texto proporcionado por la notificación.

Esto es clave, ya que le permite mostrar la alerta mientras su aplicación está abierta y en primer plano , lo cual es nuevo para iOS 10.

Código de muestra:

 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(.alert) } 

Para mostrar un mensaje de banner mientras la aplicación está en primer plano, use el siguiente método.

iOS 10, Swift 3 :

 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .badge, .sound]) } 

EDITAR:

¡Las alertas de primer plano ahora son posibles en iOS 10! Por favor mira esta respuesta .

Para iOS 9 y abajo:

Parece que no es posible mostrar la alerta de notificación de stock iOS cuando su aplicación está abierta y en primer plano. Messages.app debe estar usando una API privada.

El sistema no muestra ninguna alerta, identifica el ícono de la aplicación ni reproduce ningún sonido cuando la aplicación ya está en primer plano. – Documentos de UILocalNotification

Se UIApplicationDelegate métodos UIApplicationDelegate , lo que permite que su aplicación responda a la notificación local o remota:

 application:didReceiveLocalNotification: application:didReceiveRemoteNotification: 

Sin embargo, la IU del banner de alerta de notificación de stock de stock no se mostrará como en el Messages.app de Apple, que debe estar utilizando una API privada.

Lo mejor que puede hacer es desplegar su propio banner de alerta o utilizar un marco existente:

 -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Use a 3rd party toast alert framework to display a banner [self toastAlertFromGithub] } 

He abierto un radar para este comportamiento aquí: rdar://22313177

Para mostrar notificaciones mientras la aplicación está abierta, necesitamos manejarla manualmente. Entonces, lo que estoy haciendo a continuación es manejar la notificación una vez recibida.

Agregue todo lo siguiente en AppDelegate.m

  1. Manejar llamada para notificar
  2. Cree una vista, agregue AppIcon, mensaje de notificación y muéstrelo como una animación
  3. Agrega Touch Recogniser para eliminarlo si lo tocas o lo quitas en 5 segundos con animación.

Avísame si esta es una buena solución. Funcionó bien para mí, pero no estoy seguro si este es el camino correcto.

 - (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSString *notifMessage = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]; //Define notifView as UIView in the header file [_notifView removeFromSuperview]; //If already existing _notifView = [[UIView alloc] initWithFrame:CGRectMake(0, -70, self.window.frame.size.width, 80)]; [_notifView setBackgroundColor:[UIColor blackColor]]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,15,30,30)]; imageView.image = [UIImage imageNamed:@"AppLogo.png"]; UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 15, self.window.frame.size.width - 100 , 30)]; myLabel.font = [UIFont fontWithName:@"Helvetica" size:10.0]; myLabel.text = notifMessage; [myLabel setTextColor:[UIColor whiteColor]]; [myLabel setNumberOfLines:0]; [_notifView setAlpha:0.95]; //The Icon [_notifView addSubview:imageView]; //The Text [_notifView addSubview:myLabel]; //The View [self.window addSubview:_notifView]; UITapGestureRecognizer *tapToDismissNotif = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissNotifFromScreen)]; tapToDismissNotif.numberOfTapsRequired = 1; tapToDismissNotif.numberOfTouchesRequired = 1; [_notifView addGestureRecognizer:tapToDismissNotif]; [UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{ [_notifView setFrame:CGRectMake(0, 0, self.window.frame.size.width, 60)]; } completion:^(BOOL finished) { }]; //Remove from top view after 5 seconds [self performSelector:@selector(dismissNotifFromScreen) withObject:nil afterDelay:5.0]; return; } //If the user touches the view or to remove from view after 5 seconds - (void)dismissNotifFromScreen{ [UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{ [_notifView setFrame:CGRectMake(0, -70, self.window.frame.size.width, 60)]; } completion:^(BOOL finished) { }]; } 

Aquí está el código para recibir notificaciones push cuando la aplicación está en primer plano o en el escenario abierto, iOS 10 y Swift 2.3

 @available(iOS 10.0, *) func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) { completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge]) } 

Si necesita acceder a userInfo de notificación use code: notification.request.content.userInfo

El método userNotificationCenter(_:willPresent:withCompletionHandler:) solo se userNotificationCenter(_:willPresent:withCompletionHandler:) si agrega a la carga útil el atributo content-available:1 . La carga útil final debería ser algo así como:

 { "aps":{ "alert":"Testing.. (7)", "badge":1,"sound":"default" }, "content-available":1 } 
 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.body = body; content.userInfo = userInfo; content.sound = [UNNotificationSound defaultSound]; [content setValue:@(YES) forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { DLog(@"Error:%@", error); }]; 

Puedo mostrar la notificación de inserción cuando la aplicación está activa para iOS 10.

  1. La notificación de inserción del servidor debe ser silenciosa .

  2. Cuando reciba notificaciones remotas del servidor, envíe una notificación local y establezca el valor de keyPath: shouldAlwaysAlertWhileAppIsForeground = True

Puede manejar la notificación usted mismo y mostrar una alerta personalizada. Las aplicaciones como Viber, Whatsapp y BisPhone usan este enfoque.

Un ejemplo de alerta personalizada de terceros es CRToast .

Intente progtwigr una notificación local mientras su aplicación está en primer plano, y verá que no se muestra ninguna alerta de stock de iOS:

 if (application.applicationState == UIApplicationStateActive ) { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.userInfo = userInfo; localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertBody = message; localNotification.fireDate = [NSDate date]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; } 

Swift 3 versión

Esto muestra una alerta cuando la aplicación está en primer plano.

 if #available(iOS 10.0, *) { // need to setup the global notification delegate somewhere when your app starts // UNUserNotificationCenter.current().delegate = applicationDelegate // to show a message // let content = UNMutableNotificationContent() content.body = "MESSAGE" let request = UNNotificationRequest(identifier: "fred", content: content, trigger: nil) UNUserNotificationCenter.current().add(request) { error in // called when message has been sent debugPrint("Error: \(error)") } } 

Implementación de UNUserNotificationCenterDelegate de UNUserNotificationCenterDelegate

 @available(iOS 10.0, *) public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert]) // only-always show the alert } 

Para mostrar la notificación local esta es la mejor opción. necesita menos código para wright “BRYXBanner” https://cocoapods.org/pods/BRYXBanner

 let banner = Banner(title: "title", subtitle: "subtitle", image: UIImage(named: "addContact"), backgroundColor: UIColor(red:137.0/255.0, green:172.0/255.0, blue:2.0/255.0, alpha:1.000)) banner.dismissesOnTap = true banner.show(duration: 1.0) 

Si su destino de despliegue> = iOS10, use UNUserNotification como se muestra a continuación-

 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // Change this to your preferred presentation option completionHandler([.alert, .sound]) }