UILocalNotification 的使用

@IBAction func sendNotification(sender: AnyObject) {
        var userInfo = Dictionary<String,String>()
        userInfo["uid"]="123456"

        localNotification.alertAction = "Testing notifications on iOS8"
        localNotification.alertBody = "WoWWWWWW background"
        // 触发时间
        localNotification.fireDate = NSDate() //立即触发
        //localNotification.fireDate = NSDate().dateByAddingTimeInterval(10) //10s后触发
        localNotification.applicationIconBadgeNumber = 7 //设置app 图标上的数字
        localNotification.timeZone = NSTimeZone.defaultTimeZone() 
        //设置重复触发的间隔, 不设置的时候,只发一次. 这里的间隔只能是固定的几种日历单位,不能随意设置间隔
        localNotification.repeatInterval = NSCalendarUnit.MinuteCalendarUnit 
        localNotification.userInfo = userInfo

        UIApplication.sharedApplication().scheduleLocalNotification(localNotification) //按照 localNotification 设置的时间触发
        //UIApplication.sharedApplication().presentLocalNotificationNow(localNotification) //马上触发
    }

这种通知的限制是,只有当 App 的后台运行的时候或者没有运行的时候(一段时间内,应该是十分钟)才会触发. 如果要在前台运行的时候也触发,需要重写 Appdelegate 中的
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification)

基于 AppDelegate 的这种实现, 可以变线的实现在上面localNotification.repeatInterval 无法实现的自定义时间间隔触发的功能. 也就是在 AppDelegate 中接收到通知后自己再次发送通知

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

        var userInfoString = ""
        localNotification.alertAction = notification.alertAction
        if let userInfoDic = notification.userInfo as? Dictionary<String,String> {
        //这里可以获取到发送通知时设置的 userInfo        
            userInfoString = userInfoDic["uid"]!
        }
        localNotification.alertBody = notification.alertBody!+"from AppDelegate:\(userInfoString)"
        localNotification.fireDate = NSDate().dateByAddingTimeInterval(10)
        UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
    }

最后, 已经注册的通知,要手动 cancel 掉.
一种简单粗暴, cancel 掉所有的:

UIApplication.sharedApplication().cancelAllLocalNotifications()

另外如果要只 cancel 指定的通知, 可以利用 userInfo 来实现.比如下面的通过自定义的一个 Uid 来实现

func cancelLocalNotificationByUid(uid: String) {
        let allLocalNotifications = UIApplication.sharedApplication().scheduledLocalNotifications as! [UILocalNotification]
        for currentLocalNotification in allLocalNotifications {
            if let userInfo = currentLocalNotification.userInfo as? Dictionary<String,String> {
                if userInfo["uid"] == uid {
                    UIApplication.sharedApplication().cancelLocalNotification(currentLocalNotification)
                }
            }
        }
    }

2015-07-23更新:
通过didReceiveLocalNotification方法可以实现当 App 在前台运行的时候也发送通知, 但这个通知并不会像在后台运行的时候一样, 在屏幕上方显示, 而只是静静的躺在通知栏里. 现在能想到的办法是自定义一个 UIAlertView 模仿 UILocalNotification 的那种样式来实现.

从一个在玩 tweeter 的同事那里看到有个叫tweetbot的 app 能实现这种功能, 在 app 的前台运行的时候照样会在屏幕上方弹出一个通知, 与 UILocalNotification 的弹出几乎一模一样.

2015-07-21 14:2741