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 🙂