如何正确使用cancelLocalNotification?

时间:2015-10-08 19:54:09

标签: ios swift notifications uilocalnotification

我相信我正在使用cancelLocalNotification

我有一个有条件运行的定期通知,它是使用以下代码创建的:

let localNotification: UILocalNotification = UILocalNotification()
localNotification.alertAction = "Inactive Membership"
localNotification.alertBody = "Our system has detected that your membership is inactive..."
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.repeatInterval = .Minute  

UIApplication.sharedApplication().scheduleLocalNotification(localNotification)

此通知每隔一分钟成功运行一次(用于测试目的)。显然,我想要一种有条件删除这些通知的方法,所以我尝试使用cancelLocalNotification这样做。

我认为cancelLocalNotification如何运作

我的直觉是cancelLocalNotification将删除该特定通知对象的所有通知。以下是我如何使用它。

UIApplication.sharedApplication().cancelLocalNotification(localNotification)

实际发生的事情

我已经完成了我的功能,并确认cancelLocalNotification代码已被调用。但是,我每分钟都会收到通知。

我的问题

如何正确取消已安排的UILocalNotification?

完整代码:

static func evaluateMemberStatusNotifications() {
    let userDefaults = Global.app.userDefaults
    let localNotification: UILocalNotification = UILocalNotification()

    print("evaluating profile notifications")
    // is the user active? if so no notification
    let isActive : Bool = userDefaults.valueForKey("ActiveMember") as! Bool // false == inactive

    print("is the user active?")
    if !isActive {
        print("user is not active, checking if notification code has run")

        // if userDefaults is nil for this value, we'll set it to false
        if (userDefaults.valueForKey("ProfileNotificationHasRun") == nil) {
            print("nil! setting ProfileNotificationHasRun to 'false'")
            userDefaults.setValue(false, forKey: "ProfileNotificationHasRun")
        }

        let statusNotification = userDefaults.valueForKey("ProfileNotificationHasRun") as! Bool
        // has this code been run? If not run it
        if !statusNotification {
            print("running notification code")
            // we schedule a notification

            localNotification.alertAction = "Inactive Membership"
            localNotification.alertBody = "Our system has detected that your membership is inactive."
            localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
            localNotification.category = "status"
            localNotification.repeatInterval = .Day
            UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
            userDefaults.setValue(true, forKey: "ProfileNotificationHasRun")
        } else {
            print("notification code has already run, time interval has been set")
        }
    } else {
        print("member is active, remove Inactive notification")
        // if the member is active, we remove the notification so the user doesn't
        // keep getting notified
        UIApplication.sharedApplication().cancelLocalNotification(localNotification)

        userDefaults.setValue(false, forKey: "ProfileNotificationHasRun")
    }

}

1 个答案:

答案 0 :(得分:4)

您正在创建一个新的UILocalNotification(您的要点的第3行),然后取消它。从未安排过这个新通知。您需要获取现有的预定通知对象并取消该通知对象。

您可以通过UIApplication.sharedApplication().scheduledLocalNotifications阵列访问现有的预定通知。

或者您可以通过拨打UIApplication.sharedApplication().cancelAllLocalNotifications()取消所有预定的本地通知。

更新

每次调用evaluateMemberStatusNotifications都会创建UILocalNotification的新实例,然后(取决于ActiveMember值)配置并安排新通知,或尝试删除新通知(未安排) )通知。

相反,您应该只在!isActive分支中创建一个新通知,以便安排它。

在另一个分支中,您需要在scheduledLocalNotifications数组中找到现有通知,并且(如果找到)取消现有通知。

由于您说您还有其他通知,但您不应该使用通知的userInfo属性来识别它。例如,在安排通知之前配置通知时:

localNotification.alertAction = "Inactive Membership"
localNotification.alertBody = "Our system has detected that your membership is inactive. You may continue using this application though some features may not be available to you until your membership is reinstated."
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.category = "status"
localNotification.repeatInterval = .Day
// *** NEW
localNotification.userInfo = [ "cause": "inactiveMembership"]

如果您想取消现有通知:

let maybeNotification = UIApplication.sharedApplication().scheduledLocalNotifications?.filter({ (notification: UILocalNotification) -> Bool in
    notification.userInfo?["cause"] as? String == "inactiveMembership"
}).first
if let notification = maybeNotification {
    UIApplication.sharedApplication().cancelLocalNotification(notification)
}