Ios 为什么取消本地通知会触发重复的本地通知(生成该本地通知的通知)?

Ios 为什么取消本地通知会触发重复的本地通知(生成该本地通知的通知)?,ios,notifications,Ios,Notifications,我有一个iOS应用程序,它有一个(每天)重复的本地通知,当某些条件满足时,会触发一个新的本地通知。必须在应用程序(带有横幅)和通知视图中显示的本地通知。我已经在AppDelegate中大致实现了它,作为概念证明,它是有效的(tm) 从横幅中的一个块中,我使用取消本地通知从通知视图中删除一次性本地通知。但令人惊讶的是,当触发UIApplication.sharedApplication().cancelLocalNotification()时,会重新触发重复的本地通知-为什么?我该如何防止这种情况

我有一个iOS应用程序,它有一个(每天)重复的本地通知,当
某些
条件满足时,会触发一个新的本地通知。必须在应用程序(带有横幅)和
通知视图中显示的本地通知。我已经在AppDelegate中大致实现了它,作为概念证明,它是有效的(tm)

从横幅中的一个块中,我使用
取消本地通知
通知视图
中删除
一次性
本地通知。但令人惊讶的是,当触发
UIApplication.sharedApplication().cancelLocalNotification()
时,会重新触发重复的本地通知-为什么?我该如何防止这种情况

...
import JCNotificationBannerPresenter

...
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Setup local notifications support
        let notificationType: UIUserNotificationType
        = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
        let settings = UIUserNotificationSettings(forTypes: notificationType,
                                                  categories: nil)
        application.registerUserNotificationSettings(settings)

        // Clean up and reset
        application.applicationIconBadgeNumber = 0
        application.cancelAllLocalNotifications()

        NSLog("Setup one repeating notification")
        let n = UILocalNotification()
        n.fireDate = NSDate(timeIntervalSinceNow: 15)
        n.soundName = UILocalNotificationDefaultSoundName
        n.timeZone = NSTimeZone.defaultTimeZone()
        n.applicationIconBadgeNumber = 0
        n.userInfo = ["id": "dailyreminder"]
        n.repeatInterval = NSCalendarUnit.Day

        UIApplication.sharedApplication().scheduleLocalNotification(n)

        return true
    }

    ...

    func application(application: UIApplication,
                     didReceiveLocalNotification notification: UILocalNotification) {

        NSLog("application(... didReceiveLocalNotification/////////////////////////")
        NSLog(notification.description)

        let state = application.applicationState
        if let userInfo = notification.userInfo,
           let id = userInfo["id"] as? String
           where id != "dailyreminder" {
            switch state {
            case UIApplicationState.Active:
                NSLog(String(format: "%@ > UIApplicationState.Active", id))
                JCNotificationCenter.enqueueNotificationWithTitle(
                    notification.alertTitle,
                    message: notification.alertBody,
                    tapHandler: { () -> Void in
                        NSLog("Banner click ///////////////////////////////////////////////")
                        // 1. Go to somewhere in the app 
                        // 2. Cancel the notification from the `notifications view`
                        UIApplication.sharedApplication().cancelLocalNotification(notification)
                        // `cancel` results in an additional call up of the "dailyreminder" ~ why?
                    })
            case UIApplicationState.Inactive:
                NSLog(String(format: "%@ > UIApplicationState.Inactive", id))
                // This is called up when user selects the notification within the `notifications view`
                // and canceled by user touch.
            default:
                let desc = state.rawValue.description
                NSLog(String(format: "%@ > Unexpected app state: %@", id, desc))
            }
        }

        if let userInfo = notification.userInfo,
           let id = userInfo["id"] as? String
           where id == "dailyreminder" {
            NSLog("Repeating daily reminder was called ~ lets fire a noti to show the user")

            // Some condition checks that need to be true before firing the local notification
            if true {
                let n = UILocalNotification()
                n.fireDate = nil
                n.timeZone = NSTimeZone.defaultTimeZone()
                n.applicationIconBadgeNumber = ++UIApplication.sharedApplication().applicationIconBadgeNumber
                n.userInfo = [
                    "id": "onetimenotification"
                ]
                n.alertTitle = "One time notification title"
                n.alertBody = "One time notification body"

                UIApplication.sharedApplication().scheduleLocalNotification(n)
            }
        }

    }

    ...
更新1 我已经举了一个完整的例子

更新2 好吧,我再拍一次。将取消通知置于块之外可以工作(但不适合场景):

我还想消除
jNotificationBannerPresenter
导致异常行为的原因,因此我尝试使用新的ios AltertControl:

case UIApplicationState.Active:
    NSLog(String(format: "%@ > UIApplicationState.Active", id))
    let alertController = UIAlertController(
            title: "Daily reminder title",
            message: "Daily reminder description.",
            preferredStyle: .Alert)

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { _ in
    NSLog("Do nothing ////////////////////// ")
    }
    alertController.addAction(cancelAction)
    let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
        NSLog("OK was pressed ////////////// ")
        UIApplication.sharedApplication().cancelLocalNotification(notification)
    }
    alertController.addAction(OKAction)

    self.window!.makeKeyAndVisible()
    let v = self.window!.rootViewController!
    v.presentViewController(alertController,
                            animated: true,
                            completion: {})

不幸的是,这确实重现了这种奇怪的行为,所以它尝起来就像是块和
UIApplication.sharedApplication()的组合。取消通知(notification)

您没有取消重复通知,即您的
didReceiveLocalNotification
方法中的每日提醒通知。您已取消通知
where id!=“DailReminder”
而您重复的通知具有
id==“DailReminder”
。请在
didReceiveLocalNotification

中检查您的条件。对不起,我的问题/描述不清楚。我不想删除重复通知,但只想在单击应用程序内的横幅时删除
一次性
通知。由于
onetime
通知已被触发,我无法在
UIApplication.sharedApplication().scheduledLocalNotifications
中通过userInfo[“id”]查找它。我真的不明白您为什么要在收到通知时安排另一个通知。我的理解是,当触发重复通知时,您需要执行一些任务。正确的?如果是这种情况,那么在didReceiveLocalNotification中检查该通知的用户信息&如果该通知具有id==“daily reminder”,则执行任务、显示自定义视图或任何您想要的内容。不需要安排另一个通知,然后执行您想要的任务。这很公平。重复的每日提醒通知必须始终触发。在某些情况下可能不会触发一次性通知。在本例中,这些条件总是设置为true。如果触发了
onetime
通知,我希望在应用程序中能够从全局/系统通知视图中删除
onetime
通知。如果我解释得很尴尬,请原谅。我仍然相信用例:)好的,如果您的一次性通知在某些条件下不会被触发,那么您可以在didReceiveLocalNotification方法中使用您的id条件和该条件。
case UIApplicationState.Active:
    NSLog(String(format: "%@ > UIApplicationState.Active", id))
    let alertController = UIAlertController(
            title: "Daily reminder title",
            message: "Daily reminder description.",
            preferredStyle: .Alert)

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { _ in
    NSLog("Do nothing ////////////////////// ")
    }
    alertController.addAction(cancelAction)
    let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
        NSLog("OK was pressed ////////////// ")
        UIApplication.sharedApplication().cancelLocalNotification(notification)
    }
    alertController.addAction(OKAction)

    self.window!.makeKeyAndVisible()
    let v = self.window!.rootViewController!
    v.presentViewController(alertController,
                            animated: true,
                            completion: {})