美文网首页
ios10本地通知

ios10本地通知

作者: 金风细细 | 来源:发表于2016-11-17 09:22 被阅读1495次

    本地通知

    需要加引用.加库

    引用库

    swift写法:

    import UserNotifications
    

    oc写法:

    #import <UserNotifications/UserNotifications.h>
    

    一. 注册通知

    • 通知中心只有一个,用类方法UNUserNotificationCenter.current()获取

    • requestAuthorization后,弹出对话框让用户选择,是否同意通知权限.用户选择一次后,下次再也不会弹出了,会默认认定上次用户的选择结果.
      granted参数:
      为true: 用户同意,请求权限成功
      为false: 用户拒绝,请求通知权限失败

    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
    
    //最好能立刻指定代理 ,该代理的文档说:delegate必须在app结束launch的时候设置,可以在appdelegate的
    //application(_:willFinishLaunchingWithOptions:)或者 application(_:didFinishLaunchingWithOptions:)中设置
    center.delegate = self
    
    • 有人会说:用户也可以后期在设置中修改通知设置,确实.
      所以用这个方法实时获取用户的设置:
     center.getNotificationSettings { (UNNotificationSettings) in
          print("settsing is :\(UNNotificationSettings)")
     }
    

    二. 发送通知

    • 创建一个[UNNotificationRequest,把它add到通知中心中

    • trigger决定通知的发送情况,是重复发送,还是一次.有好几种:

    1. UNCalendarNotificationTrigger : 日历闹钟,和NSDateComponents结合,可以做到在每天指定的时刻发送通知,官网例子:
    let date = DateComponents()date.hour = 8date.minute = 30
     let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
    
    1. UNTimeIntervalNotificationTrigger: 定时闹钟
    2. UNLocationNotificationTrigger:地点闹钟,和CLLocationCoordinate2D结合,可以做到进入了某个固定区域时发送通知,官网例子:
    let center = CLLocationCoordinate2D(latitude: 37.335400, longitude: -122.009201)
    let region = CLCircularRegion(center: center, radius: 2000.0, identifier: "Headquarters")
    region.notifyOnEntry = true
    region.notifyOnExit = false
    let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
    

    OK!不扯远了,开始干!

    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationStringForKey("Hello!", arguments: nil)
    content.body = NSString.localizedUserNotificationStringForKey("Hello_message_body", arguments: nil)
    content.sound = UNNotificationSound.default()
     // Deliver the notification in five seconds.
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    let request = UNNotificationRequest(identifier: "FiveSecond", content: content, trigger: trigger)
     // Schedule the notification.
    let center = UNUserNotificationCenter.current()
    center.add(request)
    

    三. 代理方法

    通知到达后,两个代理方法:

    1. willPresent...
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Swift.Void){
    
      completionHandler([UNNotificationPresentationOptions.alert, UNNotificationPresentationOptions.badge, UNNotificationPresentationOptions.sound])
            
      //completionHandler([])
    }
    

    注意:

    • 这个方法是app在前台时进入的.app如果在后台不会进入

    • 请务必在最后一句写上completionHandler,同时指定你需要的通知到达时的形式.另外,如果想通知达到时不做任何事情,swift写:completionHandler([]) oc写:completionHandler(UNNotificationPresentationOptionNone);

    • completionHandler后的任何代码都不执行,所以让completionHandler放在你的逻辑代码之后

    • app在前台时,通知形式可以指定,那么app在后台呢?文档告诉我们,届时的通知形式由我们注册通知中心时申请的形式,以及用户在设置里面的选择共同决定,当然,在选择上,用户设置的形式 是高于 我们申请的形式 的优先级的.

    2. 点击通知才会进入的方法didReceive
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void){
       completionHandler()
    }
    

    **注意: **

    • UNNotificationResponse的属性actionIdentifier:
      用户点击的category的哪个action的identifier.如果用户是直接点击的通知,没点action,这个值是default,请自行打印了解
    • 无论app是否被杀死,无论是从横幅还是通知栏点击进入app,该方法都会被调用一次,我测试过的.

    四.其他要点

    1. 注册通知写在何处?

    官网推荐写在application:didFinishLaunchingWithOptions:
    总之不能写在scheduling一个本地/远程通知之后.

    2. 删除过期通知
    • getDeliveredNotificationsWithCompletionHandler:
      获取通知栏上的消息

    • removeDeliveredNotificationsWithIdentifiers: 删除通知栏上的消息
      如果哪个通知过期了,是你不想给用户看到的,可以删除通知栏上的消息.当然,如果用户的通知栏上本就没有这消息,可能刚到的时候就被用户点掉了,那么获取的通知栏消息数为0.可以在getDeliveredNotificationsWithCompletionHandler的回调块中去删除通知栏上的消息

    3. Action和category
    • 一个通知可以注册多个category. 发送通知时,UNMutableNotificationContent选择一个category进行绑定

    • 每个category可以有很多action,官网说最多4个,显示最多两个,我实验发现5个都行,而且全部显示-_-

    • 通知达到时,要用重力按压,就会出现action

    代码十分简单:

    let generalCategory = UNNotificationCategory(identifier: "GENERAL",
    actions: [],intentIdentifiers: [],options: .customDismissAction)
    
    // Create the custom actions for the TIMER_EXPIRED category.
    let snoozeAction = UNNotificationAction(identifier: "SNOOZE_ACTION",title: "Snooze",options: UNNotificationActionOptions(rawValue: 0))
    
    let stopAction = UNNotificationAction(identifier:"STOP_ACTION",title: "Stop",options: .foreground)
    
    let expiredCategory =UNNotificationCategory(identifier: "TIMER_EXPIRED",actions: [snoozeAction, stopAction],intentIdentifiers: [],options: UNNotificationCategoryOptions(rawValue: 0))
    
    // Register the notification categories.
    let center = UNUserNotificationCenter.current()
    
    center.setNotificationCategories([generalCategory, expiredCategory])
    

    在发送通知消息时,把UNMutableNotificationContent的categoryIdentifier赋值为category的identifier,就可以了

     let content = UNMutableNotificationContent()
            
    content.title = "coffee"
    content.body = "Time for another cup of coffee!"
    content.sound = UNNotificationSound.default()
            
    //**就是这里,要和上面的category的identifier一致**
    content.categoryIdentifier = "GENERAL";
            
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval:3, repeats:false)
    
    let request = UNNotificationRequest(identifier:"TIMER_EXPIRED", content:content,trigger:trigger)
            
    UNUserNotificationCenter.current().add(request) { error in
        print("注册成功!")
    }
    
    

    效果:

    Screen Shot 2016-11-15 at 下午2.23.32.png

    点击之后的处理

    func userNotificationCenter(_ center: UNUserNotificationCenter,
    
    didReceive response: UNNotificationResponse,
    
    withCompletionHandler completionHandler: @escaping () -> Void) {
    
    if response.notification.request.content.categoryIdentifier == "TIMER_EXPIRED" {
    
    // Handle the actions for the expired timer.
    
    if response.actionIdentifier == "SNOOZE_ACTION" {
    
    // Invalidate the old timer and create a new one. . .
    
    }
    
    else if response.actionIdentifier == "STOP_ACTION" {
    
    // Invalidate the timer. . .
    
    }
    
    }
    
    // Else handle actions for other notification types. . .
    
    }
    
    4. 官网还提供了类似"闹钟"的例子,每天七点闹醒你!
    let content = UNMutableNotificationContent()
    
    content.title = NSString.localizedUserNotificationString(forKey: "Wake up!", arguments: nil)
    
    content.body = NSString.localizedUserNotificationString(forKey: "Rise and shine! It's morning time!",
    
    arguments: nil)
    
    // Configure the trigger for a 7am wakeup.
    
    var dateInfo = DateComponents()
    
    dateInfo.hour = 7
    
    dateInfo.minute = 0
    
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: false)
    
    // Create the request object.
    
    let request = UNNotificationRequest(identifier: "MorningAlarm", content: content, trigger: trigger)
    
    5. 改变通知的声音

    通知的声音是可以改变的.UNNotificationSound.default()只是系统铃声而已.
    声音文件可以放在bundle里面,也可以在线下载,放在APP沙盒的Library/Sounds里.

    content.sound = UNNotificationSound(named: "MySound.aiff")
    

    demon
    参考:官网

    相关文章

      网友评论

          本文标题:ios10本地通知

          本文链接:https://www.haomeiwen.com/subject/ilmhpttx.html