Gérer UILocalNotification dans UIViewController en utilisant NSNotification après la fin de l'application

Je travaille avec UILocalNotification et je voudrais informer l'un de mes controllers que la notification a été reçue même si l'application a été arrêtée.

Dans mon applicationDelegate j'ai implémenté cette fonction:

 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { if ([application applicationState] == UIApplicationStateInactive) { [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:notification.userInfo]; } } 

Dans mon UIViewController j'ai implémenté l'observateur sur la méthode viewDidLoad

 - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didlocalNotificationReceived:) name:@"localNotificationReceived" object:nil]; } 

Cela fonctionne parfaitement lorsque l'application fonctionne en arrière-plan. Puisque la méthode viewDidLoad a déjà été appelée et que l'observateur est en attente.

Le problème est quand je tue l'application. Ensuite, l'observateur de mon controller est parti et la méthode didlocalNotificationReceived n'est jamais appelée.

Je pense que c'est parce que quand je reçois le localNotification et exécute l'application encore. La méthode didReceiveLocalNotification: est appelée avant la viewDidLoad de mon UIViewController . Alors l'observateur est créé après le PostNotificationName alors l'observateur ne reçoit rien.

J'aimerais savoir s'il existe des pratiques exemplaires ou des templates pour gérer ce genre de problème.

Je sais que la méthode didFinishLaunchingWithOptions est appelée avant didlocalNotificationReceived donc il y a probablement quelque chose à faire.

METTRE À JOUR :

J'ai également découvert que quand l'application est terminée. Une fois que vous appuyez sur la notification, il ouvre l'application, appelle la fonction didFinishLaunchingWithOptions mais n'appelle jamais didReceiveLocalNotification . Donc je pense que je vais gérer les deux cas différemment.

Ok j'ai trouvé la réponse.

En fait, j'initialise manuellement mon storyboard et je fais attention d'initialiser ma vue principale avant de postr le NSNotification

Ma méthode didFinishLaunchingWithOptions: dans mon appDelegate ressemble à ça:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; UIViewController *vc =[storyboard instantiateInitialViewController]; //call the initWithCoder: method of my controller if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:localNotification.userInfo]; } self.window.rootViewController = vc; [self.window makeKeyAndVisible]; return YES; } 

Ensuite, dans mon UIViewController je crée l'observateur NSNotification dans la méthode initWithCoder: au lieu de viewDidLoad:

 - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didlocalNotificationReceived:) name:@"localNotificationReceived" object:nil]; } return self; } - (void)didlocalNotificationReceived:(NSNotification *)notification { //Execute whatever method when received local notification } 

Et lorsque l'application n'est pas didReceiveLocalNotification: j'utilise toujours la méthode didReceiveLocalNotification: :

 -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { if ([application applicationState] == UIApplicationStateInactive) { [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:notification.userInfo]; } } 

Je ne suis pas sûr que ce soit la meilleure pratique. Mais ça marche bien!

J'espère que ça va aider 🙂