48 votes

Annuler UILocalNotification

J'ai un problème avec mon UILocalNotification.

Je planifie la notification avec ma méthode.

- (void) sendNewNoteLocalReminder:(NSDate *)date  alrt:(NSString *)title
{
    // some code ...
    UILocalNotification *localNotif = [[UILocalNotification alloc] init]; 

    if (localNotif == nil)  
        return;

    localNotif.fireDate = itemDate; 
    localNotif.timeZone = [NSTimeZone defaultTimeZone];
    localNotif.alertAction = NSLocalizedString(@"View Details", nil); 
    localNotif.alertBody = title;
    localNotif.soundName = UILocalNotificationDefaultSoundName; 
    localNotif.applicationIconBadgeNumber = 0;

    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:stringID forKey:@"id"]; 
    localNotif.userInfo = infoDict; 

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; 
    [localNotif release];
}

Cela fonctionne bien et je reçois correctement la notification. Le problème est de savoir quand je dois annuler la notification. J'utilise cette méthode.

- (void) deleteNewNoteLocalReminder:(NSString*) reminderID noteIDe:(NSInteger)noteIDE
{
    [[UIApplication sharedApplication] cancelLocalNotification:(UILocalNotification *)notification ????  
}

Je ne suis pas sûr de ce qu'il faut faire ici, mais mes questions sont les suivantes :

Comment savoir quel objet UILocalNotification je dois supprimer ?
Existe-t-il un moyen de lister toutes les notifications ?

La seule chose que j'ai, c'est l'ID du rappel que je dois supprimer.
Je pensais sauvegarder l'objet UILocalNotification dans mon objet "Note" et l'obtenir de cette façon, et lorsque je sauvegarde dans ma base de données SQLite, sérialiser l'objet et ainsi de suite ... y a-t-il une façon plus intelligente ?

92voto

viggio24 Points 8077

Ma solution consiste à utiliser le UILocalNotification userInfo dictionnaire. En fait, ce que je fais, c'est de générer un ID unique pour chacune de mes notifications (bien sûr, cette ID est quelque chose que je suis capable de récupérer plus tard), puis lorsque je veux annuler la notification associée à un certain ID Je vais simplement balayer toutes les notifications disponibles en utilisant le tableau :

[[UIApplication sharedApplication] scheduledLocalNotifications]

et ensuite j'essaie de faire correspondre les notifications en enquêtant sur les ID . Par exemple :

NSString *myIDToCancel = @"some_id_to_cancel";
UILocalNotification *notificationToCancel=nil;
for(UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
  if([[aNotif.userInfo objectForKey:@"ID"] isEqualToString:myIDToCancel]) {
     notificationToCancel=aNotif;
     break;
  }
}
if(notificationToCancel) [[UIApplication sharedApplication] cancelLocalNotification:notificationToCancel];

Je ne sais pas si cette approche est meilleure ou non par rapport à celle de l'archivage/désarchivage, mais elle fonctionne et limite les données à sauvegarder à un seul ID.

Edit : il manquait un frein

0 votes

J'ai essayé votre méthode et ça n'a pas marché pour moi. Pouvez-vous me dire ce qui ne va pas ? stackoverflow.com/questions/9139586/

2 votes

Vous n'utilisez pas ma méthode dans votre solution. Ma solution passe autour d'un ID, alors que vous utilisez l'objet entier. Il semble, d'après votre code, qu'il y ait eu une désallocation précoce de l'objet de notification, ce qui explique le "sélecteur non reconnu" (cela se produit généralement lorsque l'emplacement de l'ancien objet a été réutilisé par un autre type d'objet). Essayez d'obtenir le nom de classe de l'objet juste avant d'envoyer le message cancelNotification pour creuser dessus, cela peut aider au débogage. De plus, lorsque vous assignez "theNotification", utilisez "self.theNotification = ..." au lieu de "theNotificaiton = ...".

0 votes

Merci beaucoup ! Vous m'avez en fait inspiré pour ajouter un bouton sur chaque cellule où je peux : cancelLocalNotification atindex [sender tag] et cela fonctionne tellement mieux que d'amener une uialertview. Comme vous l'avez dit, le nom de l'objet est maintenant juste avant l'annulation et cela fonctionne très bien !

57voto

progrmr Points 32412

Vous pouvez obtenir une liste de toutes les notifications programmées à partir de scheduledLocalNotifications ou vous pouvez les annuler tous :

  [[UIApplication sharedApplication] cancelAllLocalNotifications];

2 votes

Je connais la fonction cancelAllLocalNotifications mais je veux juste annuler une notification spécifique. ScheduledLocalNotifications peut peut-être faire l'affaire ..... Je vais essayer.

13voto

hiepnd Points 721

Ma solution consiste à archiver l'objet UILocalNotification que vous avez programmé avec NSKeyedArchiver et à le stocker quelque part (de préférence dans une liste). Ensuite, quand vous le souhaitez, vous pouvez annuler la notification, rechercher les données correctes dans la liste et utiliser NSKeyedUnarchiver pour la désarchiver. Le code est assez simple :

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:notice];

y

UILocalNotification *notice = [NSKeyedUnarchiver unarchiveObjectWithData:data];

0 votes

Vous pouvez également sérialiser les NSData de archievedDataWithRootObject avec un encodage Base64, puis les enregistrer dans un objet JSON que vous possédez déjà.

0 votes

@RafaelSanches désolé pour le thread necro. Mais quel est l'avantage d'utiliser un objet JSON si l'objectif est de stocker/récupérer une notification uilocal pour la supprimer ultérieurement ?

6voto

Mahek Points 93

Ma solution est la suivante : lorsque vous créez UILocalNotification à ce moment-là, vous créez un NSMutableDictionary et stockez cette notification comme une valeur pour la clé comme votre ID et mettez ceci NSMutableDictionay à votre NSUserDefaults

Ainsi, lorsque vous voulez annuler une notification locale particulière, vous écrivez à ce moment-là [dictionary valueforkey @"KEY"] où, comme clé, vous passez votre identifiant pour obtenir cette notification locale particulière et la passer à

 [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];

0voto

orkoden Points 2262

Ma solution consiste à supprimer toutes les notifications programmées sur ces méthodes.

-applicationDidFinishLaunchingWithOptions: 
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;

avec

[[UIApplication sharedApplication] cancelAllLocalNotifications] ;

Vous pouvez toujours accéder à l'objet LocalNotification qui a activé votre application en utilisant.

    UILocalNotification *localNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];

Ensuite, je reprogramme les nouvelles notifications sur

- (void)applicationDidEnterBackground:(UIApplication *)application;

Cela évite d'avoir une comptabilité pour toutes les notifications. J'envoie également quelques informations contextuelles dans le dictionnaire userInfo. Cela permet ensuite d'aller au bon endroit dans l'application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X