Lorsque l'application iOS Messages officielle d'Apple est ouverte et au premier plan, les nouveaux messages d'autres contacts déclenchent une bannière d'alerte de notification native et iOS. Voir l'image ci-dessous.
Est-ce possible dans des applications tierces sur l'App Store? Notifications locales et/ou push pour votre application lorsque celle-ci est ouverte et au premier plan ?
Lors du test mon application , des notifications sont reçues mais aucune interface utilisateur d'alerte iOS n'est affichée .
Mais ce comportement est est visible dans l'application Messages officielle d'Apple:
Le Guide de programmation des notifications locales et à distance dit:
Lorsque le système d'exploitation envoie une notification locale ou une notification distante et que l'application cible est ne s'exécute pas au premier plan , il peut présenter la notification à l'utilisateur via un numéro de badge alert , ou son.
Si l'application est exécutée dans le répertoire foreground lorsque la notification est remise, le délégué de l'application reçoit une notification locale ou distante.
Alors oui, nous pouvons recevoir les données de notification au premier plan. Mais je ne vois aucun moyen de présenter l'interface utilisateur d'alerte de notification iOS native .
-(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]
}
Messages utilise-t-il alors une API privée pour afficher l'alerte en avant-plan?
Pour les besoins de cette question, veuillez ne suggérer aucune alerte contextuelle "de pain grillé" sur github ou autre. Je ne suis intéressé que si cela peut être fait à l'aide du stock, natif iOS Alertes de notification locale ou push UI lorsque votre application est ouverte et au premier plan.
iOS 10 ajoute le protocole UNUserNotificationCenterDelegate
pour le traitement des notifications lorsque votre application est au premier plan.
Le protocole
UNUserNotificationCenterDelegate
définit les méthodes de réception des notifications et de gestion des actions. Lorsque votre application est au premier plan, les notifications arrivant sont envoyées à votre objet délégué au lieu d'être affichées automatiquement à l'aide des interfaces système.
Rapide:
optional func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
Objectif c:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;
Les/ UNNotificationPresentationOptions flags vous permettent de spécifier UNNotificationPresentationOptionAlert
pour afficher une alerte en utilisant le texte fourni par la notification.
C’est essentiel car il vous permet d’afficher l’alerte lorsque votre application est ouverte et au premier plan, ce qui est nouveau pour iOS 10.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler(.alert)
}
Pour afficher le message de bannière lorsque l'application est au premier plan, utilisez la méthode suivante.
iOS 10, Swift 3 :
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
MODIFIER:
Les alertes de premier plan sont désormais possibles dans iOS 10! S'il vous plaît voir cette réponse .
Pour iOS 9 et inférieur:
Il ne semble pas possible d'afficher l'alerte de notification iOS d'origine lorsque votre application est ouverte et au premier plan. Messages.app doit utiliser une API privée.
Le système n’affiche aucune alerte, n’affiche pas l’icône de l’application ou n’émet aucun son lorsque l’application est déjà au premier plan. - Documents UILocalNotification
Les méthodes UIApplicationDelegate
will sont toujours appelées, ce qui permet à votre application de répondre à la notification locale ou à distance:
application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:
Toutefois, l'interface utilisateur de bannière d'alerte de notification iOS native ne sera ne sera pas affichée comme dans le message d'Apple, qui doit utiliser une API privée.
Le mieux que vous puissiez faire est de lancer votre propre bannière d’alerte ou d’utiliser un cadre existant:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// Use a 3rd party toast alert framework to display a banner
[self toastAlertFromGithub]
}
J'ai ouvert un radar pour ce comportement ici: rdar://22313177
Pour afficher les notifications lorsque l'application est ouverte, nous devons la gérer manuellement. Donc, ce que je fais ci-dessous est de gérer la notification une fois reçue.
Ajouter tout ce qui suit dans AppDelegate.m
Faites-moi savoir s'il s'agit d'une solution acceptable. A bien fonctionné pour moi mais je ne suis pas sûr que ce soit la bonne façon.
- (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) {
}];
}
Voici le code pour recevoir les notifications Push lorsque l'application est au premier plan ou ouverte, sous iOS 10 & 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 vous devez accéder à userInfo de notification, utilisez le code: notification.request.content.userInfo
La méthode userNotificationCenter(_:willPresent:withCompletionHandler:)
n'est appelée que si vous ajoutez à la charge l'attribut content-available:1
. La charge finale devrait être quelque chose comme:
{
"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);
}];
Je peux afficher la notification Push lorsque l'application est active pour iOS 10.
La notification Push du serveur doit être silent .
Lorsque vous recevez une notification distante du serveur, vous envoyez une notification locale et définissez la valeur pour keyPath: shouldAlwaysAlertWhileAppIsForeground = True
Vous pouvez gérer vous-même la notification et afficher une alerte personnalisée. Des applications telles que Viber, Whatsapp et BisPhone utilisent cette approche.
Un exemple d'alerte personnalisée par un tiers est CRToast .
Essayez de planifier une notification locale pendant que votre application est au premier plan et vous verrez qu'aucune alerte stock iOS n'est affichée:
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];
}
Version Swift 3
Cela montre une alerte lorsque l'application est au premier plan.
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)")
}
}
Implémentation de UNUserNotificationCenterDelegate
par ApplicationDelegate
@available(iOS 10.0, *)
public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([.alert]) // only-always show the alert
}
Pour afficher la notification locale, il s'agit de la meilleure option. nécessite moins de code pour écrire "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 votre cible de déploiement> = iOS10, utilisez UNUserNotification comme ci-dessous -
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
// Change this to your preferred presentation option
completionHandler([.alert, .sound])
}