Je souhaite ouvrir un contrôleur de vue spécifique lorsqu'un utilisateur clique sur le message de notification Push reçu, mais lorsque je reçois un message de notification Push et que je clique sur le message, seule l'application s'ouvre, mais elle ne redirige pas vers un contrôleur de vue spécifique.
Mon code est
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (applicationIsActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Bildirim"
message:[NSString stringWithFormat:@"%@ ",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]
delegate:self cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
UIViewController *vc = self.window.rootViewController;
PushBildirimlerim *pvc = [vc.storyboard instantiateViewControllerWithIdentifier:@"PushBildirimlerim "];
[vc presentViewController:pvc animated:YES completion:nil];
}
}
Ma question concerne les notifications push iOS.
Vous pouvez avoir des problèmes avec la condition if (applicationIsActive)
.
Placez un point d'arrêt sur -didReceiveRemoteNotification
et voyez s'il s'exécute dans différents scénarios et voyez s'il entre dans la condition if-.
(non apparenté dans une certaine mesure mais mérite d'être vérifié) cette question:
didReceiveRemoteNotification en arrière-plan
-didReceiveRemoteNotification
ne sera pas exécuté si votre application était fermée (initialement) et que vous avez cliqué sur la notification Push pour ouvrir l'application.
Cette méthode est exécutée lorsqu'une notification Push est reçue alors que l'application est au premier plan ou lorsque l'application passe de l'arrière-plan à l'avant-plan.
Référence Apple: https://developer.Apple.com/documentation/uikit/uiapplicationdelegate
Si l'application est en cours d'exécution et reçoit une notification à distance, l'application appelle cette méthode pour traiter la notification. Votre implémentation de cette méthode doit utiliser la notification pour suivre un cours approprié d'action.
...
Si l'application ne s'exécute pas lorsqu'une notification Push arrive, la méthode lance l'application et fournit les informations appropriées dans le fichier lance le dictionnaire des options. L'application n'appelle pas cette méthode pour gérer cette notification Push. Au lieu de cela, votre implémentation du application: willFinishLaunchingWithOptions: ou application: didFinishLaunchingWithOptions: La méthode doit obtenir le Poussez les données de notification et répondez de manière appropriée.
Alors ... Lorsque l'application est non en cours d'exécution et qu'une notification Push est reçue, lorsque l'utilisateur clique sur la notification Push, l'application est lancée et maintenant... la notification Push le contenu sera disponible dans la méthode -didFinishLaunchingWithOptions:
dans son paramètre launchOptions
.
En d'autres termes ... -didReceiveRemoteNotification
n'exécutera pas cette heure et vous devrez également le faire:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
NSDictionary *userInfo = [launchOptions valueForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];
if(apsInfo) {
//there is some pending Push notification, so do something
//in your case, show the desired viewController in this if block
}
//...
}
Lire aussi le document d'Apple sur le traitement des notifications locales et distantes
Il y a un espace supplémentaire dans le nom de l'identifiant. Supprimez-le et essayez:
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
PushBildirimlerim* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:@"PushBildirimlerim"];
[self.window.rootViewController presentViewController:pvc animated:YES completion:NULL];
J'avais le même problème que lorsque l'application est suspendue/arrêtée et que la notification Push arrive, mon application ne faisait que s'ouvrir et ne pas être redirigé vers un écran spécifique correspondant à cette notification de la solution
dans - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
cette méthode, le paramètre launchOptions
nous indique si elle dispose de la notification en vérifiant que nous devons appeler la méthode pour la rediriger vers un écran spécifique
le code est comme ci-dessous ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//your common or any code will be here at last add the below code..
NSMutableDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification)
{
//this notification dictionary is same as your JSON payload whatever you gets from Push notification you can consider it as a userInfo dic in last parameter of method -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
NSLog(@"%@",notification);
[self showOfferNotification:notification];
}
return YES;
}
puis dans la méthode showOfferNotification: notification, vous pouvez rediriger l'utilisateur vers l'écran correspondant comme ...
//** added code for notification
-(void)showOfferNotification:(NSMutableDictionary *)offerNotificationDic{
//This whole is my coding stuff.. your code will come here..
NSDictionary *segueDictionary = [offerNotificationDic valueForKey:@"aps"];
NSString *segueMsg=[[NSString alloc]initWithFormat:@"%@",[segueDictionary valueForKey:@"alert"]];
NSString *segueID=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"id"]];
NSString *segueDate=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"date"]];
NSString *segueTime=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"time"]];
NSLog(@"Show Offer Notification method : segueMsg %@ segueDate %@ segueTime %@ segueID %@",segueMsg,segueDate,segueTime,segueID);
if ([segueID isEqualToString:@"13"]){
NSString *advertisingUrl=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"advertisingUrl"]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:segueMsg forKey:@"notificationMsg"];
[defaults setObject:segueDate forKey:@"notifcationdate"];
[defaults setObject:segueTime forKey:@"notifcationtime"];
[defaults setObject:advertisingUrl forKey:@"advertisingUrl"];
[defaults synchronize];
navigationController = (UINavigationController *)self.window.rootViewController;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle: nil];
FLHGAddNotificationViewController *controller = (FLHGAddNotificationViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"offerViewController"];
[navigationController pushViewController:controller animated:YES];
}
}
Dans Swift 4
Si vous avez besoin de réaliser le cas ci-dessus, vous devez gérer 2 cas
Ici, je me sers de la catégorie (paramètre intégré dans la charge de notification Push pour identifier le type de notification) s’il existe plus d’un type de notification. Dans le cas où vous n’avez qu’un seul type de notification, inutile de vérifier la catégorie.
Donc pour traiter le premier cas, le code est le suivant dans AppDelegate File
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let title = response.notification.request.content.title
switch response.notification.request.content.categoryIdentifier
{
case "Second":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SecondTypeNotification"), object: title, userInfo: userInfo)
break
case "Third":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ThirdTypeNotification"), object: title, userInfo: userInfo)
break
default:
break
}
completionHandler() }
Après quoi, vous devez ajouter les observateurs dans le contrôleur de vue par défaut comme suit dans viewDidLoad.
NotificationCenter.default.addObserver(self,selector: #selector(SecondTypeNotification),
name: NSNotification.Name(rawValue: "SecondTypeNotification"),
object: nil)
NotificationCenter.default.addObserver(self,selector:#selector(ThirdTypeNotification),
name: NSNotification.Name(rawValue: "ThirdTypeNotification"),
object: nil)
Et également besoin de deux ajouter la fonction d'observation de notification pour ajouter des actions à exécuter avec le même nom utilisé dans Observer.
// Action to be taken if Push notification is opened and observer is called while app is in background or active
@objc func SecondTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
@objc func ThirdTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
Ainsi, chaque fois qu'une notification est ouverte lorsque l'application est au premier plan ou à l'arrière-plan, la procédure ci-dessus est exécutée et déplacée vers le contrôleur de vue correspondant en fonction de la catégorie dans la charge utile.
Maintenant le deuxième cas
Nous savons que lorsque l'application est inactive, la première fonction qui sera appelée lors de l'ouverture de la notification Push est
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
Nous devons donc vérifier dans cette fonction si l'application est lancée en ouvrant la notification Push ou en cliquant sur l'icône de l'application. Pour cela, une disposition nous est fournie. La fonction se présentera comme suit après avoir ajouté le code requis.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
// Register the notification categories.
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
/// Check if the app is launched by opening Push notification
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
// Do your task here
let dic = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary
let dic2 = dic?.value(forKey: "aps") as? NSDictionary
let alert = dic2?.value(forKey: "alert") as? NSDictionary
let category = dic2?.value(forKey: "category") as? String
// We can add one more key name 'click_action' in payload while sending Push notification and check category for indentifying the Push notification type. 'category' is one of the seven built in key of payload for identifying type of notification and take actions accordingly
if category == "Second"
{
/// Set the flag true for is app open from Notification and on root view controller check the flag condition to take action accordingly
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
else if category == "Third"
{
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
}
return true
}
Ensuite, vérifiez la valeur de ces indicateurs dans le contrôleur de vue par défaut dans viewdidLoad comme suit
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationSecond) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationThird) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
Cela permettra d’ouvrir un contrôleur de vue particulier lorsqu’une notification Push sera ouverte.
Vous pouvez passer par ce blog- Comment ouvrir un View Controller particulier lorsque l'utilisateur appuie sur la notification Push reçue? pour référence.