Удалить конкретное локальное уведомление - PullRequest
87 голосов
/ 14 июня 2011

Я разрабатываю приложение для будильника iPhone на основе локальных уведомлений.

При удалении будильника соответствующее локальное уведомление должно быть отменено.Но как я могу точно определить, какой объект из массива локальных уведомлений должен быть отменен?

Мне известен метод [[UIApplication sharedApplication] cancelLocalNotification:notification], но как я могу получить это «уведомление» для его отмены?

Ответы [ 13 ]

212 голосов
/ 14 июня 2011

Вы можете сохранить уникальное значение для ключа в пользовательской информации вашего локального уведомления. Получить все локальные уведомления, пройтись по массиву и удалить конкретное уведомление.

Код следующий,

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:

Если вы используете UserNotification (iOS 10+), просто выполните следующие действия:

  1. При создании контента UserNotification добавьте уникальный идентификатор

  2. Удалить определенные ожидающие уведомления, используя removePendingNotificationRequests (withIdentifiers:)

  3. Удаление определенных доставленных уведомлений с использованием removeDeliveredNotifications (withIdentifiers:)

Для получения дополнительной информации, UNUserNotificationCenter

23 голосов
/ 27 июня 2011

Другой вариант:

Прежде всего, когда вы создаете локальное уведомление, вы можете сохранить его в пользовательских значениях по умолчанию для будущего использования, Локальный объект уведомления не может быть сохранен непосредственно в пользовательских значениях по умолчанию, Этот объект должен быть сначала преобразован в объект NSData, а затем NSData можно сохранить в User defaults. Ниже приведен код для этого:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:localNotif];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString  stringWithFormat:@"%d",indexPath.row]];

После того, как вы сохранили и запланировали локальное уведомление, в будущем может возникнуть необходимость отменить любое ранее созданное вами уведомление, чтобы вы могли получить его из настроек пользователя по умолчанию.

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]];

Надеюсь, это поможет

8 голосов
/ 21 декабря 2014

Планирование и удаление уведомлений в swift:

    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)
        }
    }



}
8 голосов
/ 21 мая 2012

Вот что я делаю.

При создании уведомления сделайте следующее:

  // 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] ;

при попытке удалить это сделайте так:

 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

    }

}

Это решение должно работать для нескольких уведомлений, и вы не управляете никакими массивами, словарями или пользовательскими настройками по умолчанию. Вы просто используете данные, которые вы уже сохранили в базе данных системных уведомлений.

Надеюсь, это поможет будущим дизайнерам и разработчикам.

Счастливые ребята кодирования! : D

6 голосов
/ 04 сентября 2015

Решение iMOBDEV отлично работает для удаления определенного уведомления (например, после удаления тревоги), но особенно полезно, когда вам нужно выборочно удалить любое уведомление, которое уже сработало и все еще находится в центре уведомлений.

Возможный сценарий: оповещение для будильника срабатывает, но пользователь открывает приложение, не нажимая на это уведомление, и снова планирует этот будильник. Если вы хотите убедиться, что в центре уведомлений для данного элемента / тревоги может быть только одно уведомление, это хороший подход. Это также позволяет вам не удалять все уведомления при каждом открытии приложения, это лучше всего подходит для приложения.

  • После создания локального уведомления используйте NSKeyedArchiver, чтобы сохранить его как Data в UserDefaults. Вы можете создать ключ, равный тому, что вы сохраняете в словаре userInfo уведомления. Если он связан с объектом Core Data, вы можете использовать его уникальное свойство objectID.
  • Получите его с помощью NSKeyedUnarchiver. Теперь вы можете удалить его, используя метод cancelLocalNotification.
  • Обновите ключ на UserDefaults соответственно.

Вот версия Swift 3.1 этого решения (для целей ниже iOS 10):

магазин

// 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")

Получить и удалить

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")
}
4 голосов
/ 25 июня 2015

Swift Версия, если необходимо:

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!")
            }
        }
    }
2 голосов
/ 21 июня 2018

Решение Swift 4:

UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
  for request in requests {
    if request.content.categoryIdentifier == "identifier" {
      UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["identifier"])
    }
  }
}   
1 голос
/ 15 августа 2016

Вы можете сохранить строку с идентификатором категории при планировании уведомления следующим образом:

        localNotification.category = NotificationHelper.categoryIdentifier

, найдите и отмените при необходимости, вот так

let  app = UIApplication.sharedApplication()

    for notification in app.scheduledLocalNotifications! {
        if let cat = notification.category{
            if cat==NotificationHelper.categoryIdentifier {
                app.cancelLocalNotification(notification)
                break
            }

        }
    }
1 голос
/ 25 октября 2015

Я использую эту функцию в 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
  }

Вдохновленный ответом @ KingofBliss

1 голос
/ 18 марта 2014

Объект UILocalNotification, который вы передаете cancelLocalNotification:, будет соответствовать любому существующему объекту UILocalNotification с соответствующими свойствами.

Итак:

UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"foo";
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];

представит локальное уведомление, которое впоследствии может быть отменено с помощью:

UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"foo";
[[UIApplication sharedApplication] cancelLocalNotification:notification];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...