특정 로컬 알림 삭제


92

지역 알림을 기반으로 iPhone 알람 앱을 개발 중입니다.

알람을 삭제하면 관련 로컬 알림이 취소됩니다. 그러나 로컬 알림 배열에서 취소 할 개체를 정확히 어떻게 결정할 수 있습니까?

[[UIApplication sharedApplication] cancelLocalNotification:notification]방법을 알고 있지만 취소하려면 어떻게이 '알림'을받을 수 있습니까?

답변:


218

로컬 알림의 사용자 정보에 키의 고유 한 값을 저장할 수 있습니다. 모든 로컬 알림을 가져오고 배열을 반복하고 특정 알림을 삭제합니다.

다음과 같이 코드,

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

빠른:

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


@kingofBliss, "uidtodelete"에서 제공하라고 알려주세요. 제 경우에는 선언되지 않았기 때문입니다.
ishhhh

@ishhh itsjust strig 값은 .. 당신은 삭제 될를 선언하고 UID의 값을 초기화하기한다
KingofBliss

@kingofBliss, uid는 NSLog.dont에서 항상 null을 표시합니다.이 문제를 제거하는 방법을 알고 있습니다. 제발 도와주세요
ishhhh

@ishhh 로컬 알림을 만들 때 userinfo 사전에 uid 값을 저장 했습니까? 나는 당신이 그것을 놓친 것 같습니다.
KingofBliss 2011 년

@kingofBliss, "uid"는 자체 변수의 이름입니다. "notificationID"와 같은 중요한 이름을 사용할 수 NSDictionary있으며 UILocalNotification. 그런 다음 사용자 지정 데이터가있는 사전에 notification.userInfo 속성을 설정합니다. 이제 알림을 받으면 해당 사용자 지정 ID 또는 더 필요한 것으로 구분할 수 있습니다.
IgniteCoders

23

기타 옵션 :

우선, 로컬 알림을 생성 할 때 나중에 사용할 수 있도록 사용자 기본값에 저장할 수 있습니다. 로컬 알림 개체는 사용자 기본값에 직접 저장할 수 없습니다.이 개체는 먼저 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]];

도움이 되었기를 바랍니다


감사합니다. 먼저 구현했지만 귀하의 답변도 맞습니다. 고려해 보겠습니다. 어느 것이 더 효율적인지 말씀해 주시겠습니까? 도움을 주셔서 감사합니다 :)
Yogi

1
@Yogi : 첫 번째 답변을 보면 로컬 알림을 취소하려면 매번 for 루프를 실행해야하지만 위 답변에서는 for 루프를 실행할 필요가 없으며 로컬 알림에 직접 액세스하여 취소 할 수 있습니다. 지역 알림 및 사용자 기본 설정에서 제거, 내 대답은 당으로, 그것은 더 효율적인 방법입니다
iMOBDEV

@JigneshBrahmkhatri 귀하의 방법이 효과적입니다. 그러나 사용자가 앱을 제거하고 다시 설치하면 실패합니다.
KingofBliss

@KingofBliss,이 경우 모든 알림을 취소해야합니다. 그래서이 솔루션이 더 빠르다고 생각합니다. :)
Sufian

@Sufian 모든 알림을 취소하려면 훨씬 빠른 방법이 있습니다. [[UIApplication sharedApplication] cancelAllLocalNotifications]; ;)
KingofBliss 2013 년

8

여기 내가하는 일이 있습니다.

알림을 만들 때 다음을 수행하십시오.

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

    }

}

이 솔루션은 여러 알림에 대해 작동해야하며 어레이, 사전 또는 사용자 기본값을 관리하지 않습니다. 시스템 알림 데이터베이스에 이미 저장 한 데이터를 사용하는 것입니다.

이것이 미래의 디자이너와 개발자에게 도움이되기를 바랍니다.

행복한 코딩 녀석들! :디


답변을 공유 해주셔서 감사하지만 모든 알림이 동일한 본문을 가지고 있거나 본문이 사용자로부터 가져 오는 경우이 로직이 어떻게 작동하는지,이 경우 사용자는 여러 알림에 동일한 본문을 제공 할 수 있습니다.
Yogi

@Yogi는 alertbody처럼 필요한 알림을 받기 위해 notification.firedate를 확인할 수 있습니다. 간단한에 대한 abhi 덕분에 유 1을 solution.upvote
Azik 압둘라에게

1
@NAZIK : 토론에 관심을 가져 주셔서 감사합니다. 그러나 여전히 사용자는 알람 애플리케이션과 동일한 화재 날짜에 두 개의 알림을 예약 할 수 있습니다. 적어도 테스터에게는 테스트 케이스가 될 수 있으며이 솔루션은 실패한 것으로 보입니다.
Yogi

@ Yogi, wise testing, 왜 우리는 ([localNotification.alertBody isEqualToString : savedTitle] || [localNotification.firedate == something])인지 확인할 수 없습니다. 같은 날짜의 두 알림은 다른 alertBody를 포함해야하기 때문입니다.
Azik Abdullah

을 남용하지 마십시오 alertBody또는 fireDate통지를 식별; userInfo@KingOfBliss 세부 사항의 답변으로이 필드를 사용 하십시오.
severin

8

신속한 예약 및 removeNotification :

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



}

1
을 남용하지 마십시오 alertBody또는 fireDate통지를 식별; userInfo@KingOfBliss 세부 사항의 답변으로이 작업을 수행 하기 위해 필드를 사용 하십시오 ...
severin

예 alertBody는 알림을 식별하는 데 좋은 옵션이 아닙니다. userInfo로 변경했습니다
Roman Barzyczak

6

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

나를 위해 일했습니다. 배열이 비어 있기 때문에 다른 모든 제안은 그렇지 않습니다.
Maksim Kniazev

iOS 10에 대한 아이디어가 있습니까?
Danpe

1
@Danpe는 : 여기에 "배달 알림 관리"섹션을 살펴 가지고 developer.apple.com/reference/usernotifications/...
Rygen

Xcode가 처리 한 마이너 모드로 swift 3로 저를 위해 일했습니다.
beshio

@beshio : 고마워요. 구문을 업데이트했습니다.
Rygen

4

필요한 경우 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!")
            }
        }
    }

4

Swift 4 솔루션 :

UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
  for request in requests {
    if request.identifier == "identifier" {
      UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["identifier"])
    }
  }
}   

2

알림을 예약 할 때 카테고리 식별자와 함께 문자열을 유지할 수 있습니다.

        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

전달 cancelLocalNotification:하는 UILocalNotification 개체는 속성이 일치하는 기존 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];

1
감사. 새 알림을 만든 다음 취소하는 것 같습니다. 이전에 예약 된 알림에는 영향을주지 않으며 여전히 실행됩니다.
Yogi

alertBody를 제외한 속성과 일치 할 수있는 속성이 있습니까?
Shamsiddin 2016

1

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

신속한 3- 스타일 :

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

}

iOS 10 사용 :

    let center = UNUserNotificationCenter.current()
    center.removePendingNotificationRequests(withIdentifiers: [uidtodelete])

0

반복 알림의 경우 (예를 들어 일요일, 토요일 및 수요일 오후 4시에 알람을 실행하려면 3 개의 알람을 만들고 repeatInterval을 NSWeekCalendarUnit으로 설정해야합니다).

한 번만 알림 만들기 :

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

반복 알림 :

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

필터링을 위해 배열을 표시합니다.

-(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;
}

알림이 한 번만 또는 반복 된 경우에도 제거하려면 다음을 수행하십시오.

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

}

0

KingofBliss의 답변을 조금 확장하고 Swift2와 비슷하게 작성하고 불필요한 코드를 제거하고 크래시 가드를 추가했습니다.

시작하려면 알림을 만들 때 알림의 uid (또는 실제로 사용자 정의 속성)를 설정해야합니다 userInfo.

notification.userInfo = ["uid": uniqueid]

그런 다음 삭제할 때 다음을 수행 할 수 있습니다.

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

1
안전을 위해 당신이 app.scheduledLocalNotifications에서 schedualedNotif의 가드 문 가드하자 응용 프로그램 = UIApplication.sharedApplication () 다른 {반환 거짓}을 사용할 수 {...} 그런 다음에 대한 루프에서 포장을 벗긴 힘이 필요하지 않습니다
troligtvis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.