Supprimer une notification locale particulière
-
27-10-2019 - |
Question
Je développe une application iPhone d'alarme basé sur les notifications locales.
En supprimant une alarme, devrait être annulé la notification locale associée. Mais comment puis-je déterminer exactement quel objet à partir du tableau des notifications locales doit être annulée?
Je suis au courant de la méthode de [[UIApplication sharedApplication] cancelLocalNotification:notification]
mais comment puis-je obtenir cette « notification » pour l'annuler?
La solution
Vous pouvez enregistrer une valeur unique pour la clé dans la userinfo de votre notification locale. Obtenez toutes les notifications locales, boucle à travers le réseau et supprimer la notification particulière.
Code suit comme,
OBJ-C:
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSString *uid=[NSString stringWithFormat:@"%@",[userInfoCurrent valueForKey:@"uid"]];
if ([uid isEqualToString:uidtodelete])
{
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
SWIFT:
var app:UIApplication = UIApplication.sharedApplication()
for oneEvent in app.scheduledLocalNotifications {
var notification = oneEvent as UILocalNotification
let userInfoCurrent = notification.userInfo! as [String:AnyObject]
let uid = userInfoCurrent["uid"]! as String
if uid == uidtodelete {
//Cancelling local notification
app.cancelLocalNotification(notification)
break;
}
}
UserNotification:
Si vous utilisez UserNotification (iOS 10+), il suffit de suivre ces étapes:
-
Lors de la création du contenu UserNotification, ajoutez un identifiant unique
-
Supprimer notification en attente spécifique en utilisant removePendingNotificationRequests (withIdentifiers: )
-
Supprimer spécifique livré notification à l'aide removeDeliveredNotifications (withIdentifiers :)
Pour plus d'informations, UNUserNotificationCenter
Autres conseils
Autre option:
Tout d'abord, lorsque vous créez une notification locale, vous pouvez stocker dans les valeurs par défaut de l'utilisateur pour une utilisation future, objet de notification locale ne peut pas être stocké directement dans les valeurs par défaut de l'utilisateur, cet objet doit être converti en objet NSData d'abord, puis NSData
peuvent être stockés dans User defaults
. Ci-dessous le code pour que:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:localNotif];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString stringWithFormat:@"%d",indexPath.row]];
Une fois que vous avez enregistré et programmé une notification locale, à l'avenir, l'exigence peut se produire que vous devez annuler toute notification que vous avez créé, vous pouvez le récupérer par défaut de l'utilisateur.
NSData *data= [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%d",UniqueKey]];
UILocalNotification *localNotif = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"Remove localnotification are %@", localNotif);
[[UIApplication sharedApplication] cancelLocalNotification:localNotif];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:[NSString stringWithFormat:@"%d",UniqueKey]];
Hope this helps
Voici ce que je fais.
Lors de la création de votre notification faire ceci:
// Create the notification
UILocalNotification *notification = [[UILocalNotification alloc] init] ;
notification.fireDate = alertDate;
notification.timeZone = [NSTimeZone localTimeZone] ;
notification.alertAction = NSLocalizedString(@"Start", @"Start");
notification.alertBody = **notificationTitle**;
notification.repeatInterval= NSMinuteCalendarUnit;
notification.soundName=UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:notification] ;
lorsque vous essayez de supprimer le faire:
NSArray *arrayOfLocalNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications] ;
for (UILocalNotification *localNotification in arrayOfLocalNotifications) {
if ([localNotification.alertBody isEqualToString:savedTitle]) {
NSLog(@"the notification this is canceld is %@", localNotification.alertBody);
[[UIApplication sharedApplication] cancelLocalNotification:localNotification] ; // delete the notification from the system
}
}
Cette solution devrait fonctionner pour plusieurs notifications, et vous n'êtes pas gérer des tableaux ou des dictionnaires ou des paramètres utilisateur par défaut. Votre utilisant simplement les données que vous avez déjà enregistrées dans la base de données de notification des systèmes.
Espérons que cela aide les concepteurs et les développeurs futurs.
Bonne programmation les gars! : D
Planification et removeNotification dans rapide:
static func scheduleNotification(notificationTitle:String, objectId:String) {
var localNotification = UILocalNotification()
localNotification.fireDate = NSDate(timeIntervalSinceNow: 24*60*60)
localNotification.alertBody = notificationTitle
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.applicationIconBadgeNumber = 1
//play a sound
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertAction = "View"
var infoDict : Dictionary<String,String!> = ["objectId" : objectId]
localNotification.userInfo = infoDict;
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
static func removeNotification(objectId:String) {
var app:UIApplication = UIApplication.sharedApplication()
for event in app.scheduledLocalNotifications {
var notification = event as! UILocalNotification
var userInfo:Dictionary<String,String!> = notification.userInfo as! Dictionary<String,String!>
var infoDict : Dictionary = notification.userInfo as! Dictionary<String,String!>
var notifcationObjectId : String = infoDict["objectId"]!
if notifcationObjectId == objectId {
app.cancelLocalNotification(notification)
}
}
}
de iMOBDEV fonctionne parfaitement pour supprimer une notification spécifique (par exemple, après la suppression de l'alarme), mais il est particulièrement utile lorsque vous avez besoin pour éliminer sélectivement toute notification qui a déjà tiré et est toujours au centre de notification.
Un scénario possible serait la suivante: la notification pour un feu d'alarme, mais l'utilisateur ouvre l'application sans taper sur cette notification et des horaires qui alarme à nouveau. Si vous voulez vous assurer qu'une seule notification peut être au centre de notification pour un élément donné / alarme, il est une bonne approche. Il vous permet également de ne pas avoir à effacer toutes les notifications à chaque fois que l'application est ouverte, doit qui correspondent à l'application mieux.
- Lors de la création d'une notification locale, l'utilisation
NSKeyedArchiver
pour stocker commeData
dansUserDefaults
. Vous pouvez créer une clé égale à ce que vous vous enregistrez dans userInfo dictionnaire de la notification. Si elle est associée à un objet de données de base, vous pouvez utiliser sa propriété objectID unique. - Récupérer avec
NSKeyedUnarchiver
. Maintenant, vous êtes en mesure de le supprimer en utilisant la méthode cancelLocalNotification. - Mise à jour sur la touche
UserDefaults
en conséquence.
Voici une version Swift 3.1 de cette solution (pour les cibles ci-dessous iOS 10):
Magasin
// localNotification is the UILocalNotification you've just set up
UIApplication.shared.scheduleLocalNotification(localNotification)
let notificationData = NSKeyedArchiver.archivedData(withRootObject: localNotification)
UserDefaults.standard.set(notificationData, forKey: "someKeyChosenByYou")
Récupérer et supprimer
let userDefaults = UserDefaults.standard
if let existingNotificationData = userDefaults.object(forKey: "someKeyChosenByYou") as? Data,
let existingNotification = NSKeyedUnarchiver.unarchiveObject(with: existingNotificationData) as? UILocalNotification {
// Cancel notification if scheduled, delete it from notification center if already delivered
UIApplication.shared.cancelLocalNotification(existingNotification)
// Clean up
userDefaults.removeObject(forKey: "someKeyChosenByYou")
}
Swift Version, si besoin:
func cancelLocalNotification(UNIQUE_ID: String){
var notifyCancel = UILocalNotification()
var notifyArray = UIApplication.sharedApplication().scheduledLocalNotifications
for notifyCancel in notifyArray as! [UILocalNotification]{
let info: [String: String] = notifyCancel.userInfo as! [String: String]
if info[uniqueId] == uniqueId{
UIApplication.sharedApplication().cancelLocalNotification(notifyCancel)
}else{
println("No Local Notification Found!")
}
}
}
Swift 4 solution:
UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
for request in requests {
if request.identifier == "identifier" {
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["identifier"])
}
}
}
L'objet UILocalNotification vous passez à cancelLocalNotification:
correspondra à tout objet UILocalNotification existant avec des propriétés correspondant.
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"foo";
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
présentera une notification locale qui peut ensuite être annulée:
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"foo";
[[UIApplication sharedApplication] cancelLocalNotification:notification];
J'utilise cette fonction Swift 2.0:
static func DeleteNotificationByUUID(uidToDelete: String) -> Bool {
let app:UIApplication = UIApplication.sharedApplication()
// loop on all the current schedualed notifications
for schedualedNotif in app.scheduledLocalNotifications! {
let notification = schedualedNotif as UILocalNotification
let urrentUi = notification.userInfo! as! [String:AnyObject]
let currentUid = urrentUi["uid"]! as! String
if currentUid == uidToDelete {
app.cancelLocalNotification(notification)
return true
}
}
return false
}
Inspiré de @ Réponse de KingofBliss
Vous pouvez garder une chaîne avec l'identifiant de la catégorie lors de la planification de la notification comme si
localNotification.category = NotificationHelper.categoryIdentifier
et rechercher et annuler en cas de besoin comme si
let app = UIApplication.sharedApplication()
for notification in app.scheduledLocalNotifications! {
if let cat = notification.category{
if cat==NotificationHelper.categoryIdentifier {
app.cancelLocalNotification(notification)
break
}
}
}
Pour de multiples rappels (Par exemple, vous voulez que votre alarme incendie sur Sun, Sam et mer à 16 heures, Ensuite, vous devez faire 3 alarmes et mettre repeatInterval à NSWeekCalendarUnit).
Pour faire une fois seulement Rappel:
UILocalNotification *aNotification = [[UILocalNotification alloc] init];
aNotification.timeZone = [NSTimeZone defaultTimeZone];
aNotification.alertBody = _reminderTitle.text;
aNotification.alertAction = @"Show me!";
aNotification.soundName = UILocalNotificationDefaultSoundName;
aNotification.applicationIconBadgeNumber += 1;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsForFireDate = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate: _reminderDate];
[componentsForFireDate setHour: [componentsForFireDate hour]] ; //for fixing 8PM hour
[componentsForFireDate setMinute:[componentsForFireDate minute]];
[componentsForFireDate setSecond:0] ;
NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForFireDate];
aNotification.fireDate = fireDateOfNotification;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:_reminderTitle.text forKey:kRemindMeNotificationDataKey];
aNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:aNotification];
Pour rappel Faire répétée:
for (int i = 0 ; i <reminderDaysArr.count; i++)
{
UILocalNotification *aNotification = [[UILocalNotification alloc] init];
aNotification.timeZone = [NSTimeZone defaultTimeZone];
aNotification.alertBody = _reminderTitle.text;
aNotification.alertAction = @"Show me!";
aNotification.soundName = UILocalNotificationDefaultSoundName;
aNotification.applicationIconBadgeNumber += 1;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsForFireDate = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate: _reminderDate];
[componentsForFireDate setWeekday: [[reminderDaysArr objectAtIndex:i]integerValue]];
[componentsForFireDate setHour: [componentsForFireDate hour]] ; // Setup Your Own Time.
[componentsForFireDate setMinute:[componentsForFireDate minute]];
[componentsForFireDate setSecond:0] ;
NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForFireDate];
aNotification.fireDate = fireDateOfNotification;
aNotification.repeatInterval = NSWeekCalendarUnit;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:_reminderTitle.text forKey:kRemindMeNotificationDataKey];
aNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:aNotification];
}
}
Pour Le filtrage tableau pour l'afficher.
-(void)filterNotficationsArray:(NSMutableArray*) notificationArray{
_dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication] scheduledLocalNotifications]];
NSMutableArray *uniqueArray = [NSMutableArray array];
NSMutableSet *names = [NSMutableSet set];
for (int i = 0 ; i<_dataArray.count; i++) {
UILocalNotification *localNotification = [_dataArray objectAtIndex:i];
NSString * infoDict = [localNotification.userInfo objectForKey:@"kRemindMeNotificationDataKey"];
if (![names containsObject:infoDict]) {
[uniqueArray addObject:localNotification];
[names addObject:infoDict];
}
}
_dataArray = uniqueArray;
}
Pour supprimer Rappel même il était une fois ou répétée:
- (void) removereminder:(UILocalNotification*)notification
{
_dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication]scheduledLocalNotifications]];
NSString * idToDelete = [notification.userInfo objectForKey:@"kRemindMeNotificationDataKey"];
for (int i = 0 ; i<_dataArray.count; i++)
{
UILocalNotification *currentLocalNotification = [_dataArray objectAtIndex:i];
NSString * notificationId = [currentLocalNotification.userInfo objectForKey:@"kRemindMeNotificationDataKey"];
if ([notificationId isEqualToString:idToDelete])
[[UIApplication sharedApplication]cancelLocalNotification:currentLocalNotification];
}
_dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication]scheduledLocalNotifications]];
[self filterNotficationsArray:_dataArray];
[_remindersTV reloadData];
}
J'Elargi de la réponse de KingofBliss un peu, écrit ce un peu plus Swift2 comme, enlevé un peu de code inutiles, et a ajouté dans certains gardes crash.
Pour commencer, lors de la création de la notification, vous devez vous assurer que vous définissez l'uid (ou toute propriété personnalisée vraiment) de userInfo
de la notification:
notification.userInfo = ["uid": uniqueid]
Ensuite, lors de la suppression, vous pouvez le faire:
guard
let app: UIApplication = UIApplication.sharedApplication(),
let notifications = app.scheduledLocalNotifications else { return }
for notification in notifications {
if
let userInfo = notification.userInfo,
let uid: String = userInfo["uid"] as? String where uid == uidtodelete {
app.cancelLocalNotification(notification)
print("Deleted local notification for '\(uidtodelete)'")
}
}
rapide 3-style:
final private func cancelLocalNotificationsIfIOS9(){
//UIApplication.shared.cancelAllLocalNotifications()
let app = UIApplication.shared
guard let notifs = app.scheduledLocalNotifications else{
return
}
for oneEvent in notifs {
let notification = oneEvent as UILocalNotification
if let userInfoCurrent = notification.userInfo as? [String:AnyObject], let uid = userInfoCurrent["uid"] as? String{
if uid == uidtodelete {
//Cancelling local notification
app.cancelLocalNotification(notification)
break;
}
}
}
}
pour iOS 10:
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: [uidtodelete])