iOS10推送通知(本地&远程)/Swift

爷,独闯天下 提交于 2021-02-17 22:26:48

iOS10本地通知

一.发送一个简单的本地通知

1.注册通知

  • 需要导入头文件或者框架UserNotifications
  • 在iOS8.0之后,如果想要用户接收通知需要主动请求授权,为了能让该代码一定被执行,一般写在Appdelegate中
 
  1. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  2.  
  3. // 1.获取通知中心
  4. let center = UNUserNotificationCenter.current()
  5.  
  6. // 2.注册通知(会弹框请求用户授权)
  7.  
  8. // 如果有错误则直接返回
  9. if error != nil {
  10. return
  11. }
  12.  
  13. // 授权成功则为true
  14. if granted {
  15. print("用户同意通知")
  16. } else {
  17. print("用户拒绝通知")
  18. }
  19.  
  20. }

2.发送通知(点击控制器View的时候发送通知)

 
  1. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  2.  
  3. // 创建通知标识(用于标识哪一个通知)
  4. let identifier = "SimpleNotificationIdentifier"
  5.  
  6. // 创建通知中的内容
  7. let content = UNMutableNotificationContent()
  8. // 设置内容
  9. content.body = "我是内容"
  10.  
  11. // 设置通知发送的时间
  12. // 注意:重复时间必须大于60秒
  13. let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
  14.  
  15. // 创建请求对象
  16. let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
  17. // 获取通知中心
  18. let center = UNUserNotificationCenter.current()
  19.  
  20. // 添加本地通知
  21. center.add(request, withCompletionHandler: {(error: Error?) in
  22.  
  23. if error == nil {
  24. print("本地通知添加成功")
  25. }
  26. })
  27. }

3.展示效果

  • 前台没有弹框
  • 后台/退出应用/通知中心/锁屏均可以接收到弹框
    通知01

二.发送一个带附件的通知

  • 在iOS10之后发送通知的时候可以附带一些内容
    • 内容包含图片、GIF图片、视频以及音频(格式最好是caf,否则没有效果)
 
  1. /* 设置其他内容 */
  2. // 应用文字
  3. content.badge = 10
  4.  
  5. // 设置通知的声音
  6. content.sound = UNNotificationSound(named: "win.aac")
  7.  
  8. // 设置标题
  9. content.title = "我是标题"
  10.  
  11. // 设置子标题
  12. content.subtitle = "我是子标题"
  13.  
  14. // 设置附件内容
  15. // 附件标识
  16. let attachmentIdentifier = "ImageAttachmentIdentifier"
  17. // 附件URL
  18. if let url = Bundle.main.url(forResource: "70s Electric Piano 52.caf", withExtension: nil) {
  19. do {
  20. let attachment = try UNNotificationAttachment(identifier: attachmentIdentifier, url: url, options: nil)
  21. content.attachments = [attachment]
  22. print("---")
  23. } catch {
  24. print(error)
  25. }
  26. }
  • 展示的效果

图片

通知02

Gif

通知03

音频

通知04

视频
通知05

三.对通知的操作

  • 当一个通知添加成功之后,可以对添加成功的通知做一些操作,分别为:
    • 查看即将发送的通知
    • 取消即将发送的通知
    • 查看已经发送的通知
    • 取消已经发送的通知
 
  1. /// 查看即将发送的通知
  2. @IBAction func showUnsendNotification() {
  3. UNUserNotificationCenter.current().getPendingNotificationRequests { (request: [UNNotificationRequest]) in
  4. print("即将发送的通知:\(request)")
  5. }
  6. }
  7.  
  8. /// 删除即将发送的通知
  9. @IBAction func removeUnsendNotification() {
  10.  
  11. // 通过标识删除某一个通知
  12. // UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: <#T##[String]#>)
  13.  
  14. // 删除所有
  15. UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
  16. }
  17.  
  18. /// 查看发送成功的通知
  19. @IBAction func showSendedNotification() {
  20. UNUserNotificationCenter.current().getDeliveredNotifications { (notification: [UNNotification]) in
  21. print("查看发送成功的通知:\(notification)")
  22. }
  23. }
  24.  
  25. /// 删除发送成功的通知
  26. @IBAction func removeSendedNotification() {
  27.  
  28. // 通过标识删除某一个发送成功的通知
  29. // UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: <#T##[String]#>)
  30.  
  31. // 删除所有发送成功的通知
  32. UNUserNotificationCenter.current().removeAllDeliveredNotifications()
  33.  
  34. }

四.监听通知的点击

  • 当用户点击通知进入App后,监听用户通知行为
  • 需要设置通知的代理,当用户点击了通知后,会通过代理告诉我们

设置代理

 
  1. UNUserNotificationCenter.current().delegate = self

遵守协议并实现代理方法

 
  1. extension ViewController: UNUserNotificationCenterDelegate {
  2.  
  3. /// 当接收到通知的时候会来到该方法
  4. ///
  5. /// - Parameters:
  6. /// - center: 通知中心
  7. /// - response: 响应
  8. /// - completionHandler: 成功回调
  9. func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  10. print("接收到通知\(response)")
  11. completionHandler()
  12. }
  13.  
  14.  
  15. /// 当一个通知发送成功后会来到该方法
  16. ///
  17. /// - Parameters:
  18. /// - center: 通知中心
  19. /// - notification: 发送的通知
  20. /// - completionHandler: 回调闭包,可以设置在前台收到通知横幅
  21. func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  22. print("发送通知成功\(notification)")
  23.  
  24. // 在前台也能接收到通知
  25. completionHandler([.alert,.badge,.sound])
  26.  
  27. }
  28. }

五.通知的触发条件

  • iOS10与之前的通知的触发条件一共有三种
    • 多少时间之后发送通知
    • 指定日期发送通知
    • 触发区域发送通知
  • 在iOS10之后,触发条件的类为UNNotificationTrigger
  • 而具体设置需要使用到它的子类
    • UNTimeIntervalNotificationTrigger : 多少时间之后
    • UNCalendarNotificationTrigger : 指定日期
    • UNLocationNotificationTrigger : 指定区域

1.多少时间之后发送通知

注意: 如果需要重复,那么时间必须大于60秒

 
  1. let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

2.指定日期发送通知

可以通过添加年月日时,来固定一个时间发送通知

 
  1. // 创建时间组件
  2. var components = DateComponents()
  3. // 设置为日历时间
  4. components.calendar = Calendar(identifier: .gregorian)
  5. // 每天的早上10点10分发送通知
  6. components.hour = 10
  7. components.minute = 10
  8. print(components.date)
  9. let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)

3.指定区域发送通知

注意:在使用模拟器调试的过程中,可能会无法显示,重置模拟器,或者换个模拟器则会解决该问题

 
  1. // 1.请求授权(iOS8.0之后获取用户的位置要主动请求授权,注意在info.plist中配置对应的key)
  2. lazy var locationM: CLLocationManager = {
  3. let locationM = CLLocationManager()
  4. locationM.requestAlwaysAuthorization()
  5. return locationM
  6. }()
  7.  
  8. // 2.创建区域触发器
  9. let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 12.123, longitude: 123.456), radius: 1000, identifier: "RegionNotification")
  10. locationM.startMonitoring(for: region)
  11. let trigger = UNLocationNotificationTrigger(region: region, repeats: true)

六.额外操作项

1.设置通知的额外信息

 
  1. // 1.设置额外信息
  2. content.userInfo = ["name": "张三", "age": 18]
  3.  
  4. // 2.在接收到通知后,可以获取到额外信息
  5.  
  6. /// 当接收到通知的时候会来到该方法
  7. ///
  8. /// - Parameters:
  9. /// - center: 通知中心
  10. /// - response: 响应
  11. /// - completionHandler: 成功回调
  12. func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  13. print("接收到通知获取额外信息\(response.notification.request.content.userInfo)")
  14. completionHandler()
  15. }
  16. // 打印为:接收到通知获取额外信息[AnyHashable("name"): 张三, AnyHashable("age"): 18]

2.设置额外操作项

  • 步骤
    • 注册操作集合
    • 注册操作组,添加到操作集合中
    • 注册操作行为,添加到操作组中
    • 设置通知所用到的操作组
 
  1. // 1.注册操作项
  2. // 1.创建操作项
  3. let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回复", options: .foreground)
  4. let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒绝", options: .destructive)
  5. let actions: [UNNotificationAction] = [action1, action2]
  6. // 创建操作组
  7. // identifier: 操作组标识
  8. // actions: 操作组行为
  9. // intentIdentifiers:暂时未发现该用途
  10. // options: 支持的场景
  11.  
  12. let categoryIdentifier = "category1"
  13. let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)
  14. // 注册操作集合(其中设置操作组)
  15. let categories: Set<UNNotificationCategory> = [category]
  16. center.setNotificationCategories(categories)
  17.  
  18. // 设置该通知用到的额外操作组
  19. content.categoryIdentifier = "category1"
  • 展示效果
    • 点击回复打开app
    • 点击拒绝则不会打开app
    • 两者都会调用接收通知的代理方法
      *

七.设置快捷回复

  • 操作行为有2个类来实现’UNNotificationAction’以及UNTextInputNotificationAction
  • 其中UNTextInputNotificationAction是’UNNotificationAction’的子类,用于实现快捷回复
    • 下列代码中的action3 为便捷回复行为
 
  1.  
  2. // 1.创建操作项
  3. let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回复", options: .foreground)
  4. let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒绝", options: .destructive)
  5.  
  6. let action3 = UNTextInputNotificationAction(identifier: "kuaijie", title: "快捷回复", options: .foreground, textInputButtonTitle: "回复按钮", textInputPlaceholder: "占位字符")
  7. let actions: [UNNotificationAction] = [action1, action2,action3]
  8.  
  9. // 创建操作组
  10. // identifier: 操作组标识
  11. // actions: 操作组行为
  12. // intentIdentifiers:暂时未发现该用途
  13. // options: 支持的场景
  14.  
  15. let categoryIdentifier = "category1"
  16. let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)
  17. // 注册操作集合(其中设置操作组)
  18. let categories: Set<UNNotificationCategory> = [category]
  19. center.setNotificationCategories(categories)
  • 展示效果

八.通知触发的场景

  • 在实际开发中,前台获取通知与后台获取通知所要执行的逻辑不一致,那么就有必要去判断一下,当前的通知触发的场景
  • 步骤
    • 在获取到通知的代理方法中获取该应用的状态
    • 判断当前状态
 
  1. /// 当接收到通知的时候会来到该方法
  2. ///
  3. /// - Parameters:
  4. /// - center: 通知中心
  5. /// - response: 响应
  6. /// - completionHandler: 成功回调
  7. func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  8.  
  9. if let response = response as? UNTextInputNotificationResponse {
  10. print(response.userText)
  11.  
  12. } else {
  13. print("接收到通知获取额外信息\(response.notification.request.content.userInfo)")
  14.  
  15. }
  16.  
  17. let status = UIApplication.shared.applicationState
  18.  
  19. switch status {
  20. case .active:
  21. print("在前台")
  22. case .inactive:
  23. print("进入前台")
  24. default:
  25. print("在后台")
  26. }
  27.  
  28. completionHandler()
  29. }

iOS10远程推送通知

一.获取DeviceToken

  • 此处省略配置真机调试证书通知调试证书以及通知生产证书步骤
  • 必须保证BundleId与在开发者中心的AppId一致
  • 必须使用真机

1.注册通知

  • 需要导入头文件或者框架UserNotifications
  • 在iOS8.0之后,如果想要用户接收通知需要主动请求授权,为了能让该代码一定被执行,一般写在Appdelegate中
 
  1. // 1.获取通知中心
  2. let center = UNUserNotificationCenter.current()
  3.  
  4. // 2.注册通知
  5. center.requestAuthorization(options: [.alert,.carPlay,.badge,.sound], completionHandler: {(granted: Bool, error: Error?) in
  6. if error != nil {
  7. return
  8. }
  9.  
  10. if granted {
  11. print("用户允许通知")
  12. } else {
  13. print("用户拒绝通知")
  14. }
  15. })

2.向苹果服务器申请DeviceToken

  • 获取方式与iOS8.0一致
 
  1.  
  2. // 3.获取deviceToken
  3. application.registerForRemoteNotifications()
  • 从代理中获取deviceToken
    • 此处Data打印的是32types,转为NSData即可
 
  1. /// 当获取到deviceToken会来到该方法
  2. func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  3. print(NSData(data: deviceToken))
  4. }
  5.  
  6. /// 注册失败会来到该方法
  7. func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
  8. print(error)
  9. }

3.开启远程推送功能

  • 工程->target->Capabilities->Push
  • 开启的条件
    • 1.Apple Id 必须配置了远程推送通知
    • 2.权利文件(打开会自动生成该文件)

4.运行真机,获取DeviceToken

二.发送通知

  • 借助PushMeBaby作为服务器向苹果服务器发送消息,苹果服务器推送通知

极光推送

  • 注册应用
  • 上传通知证书.p12
  • 集成Jpush SDK

1.注册Jpush并获取DeviceToken

 
  1.  
  2. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  3.  
  4. // 注册通知
  5. let entity = JPUSHRegisterEntity()
  6. entity.types = Int(JPAuthorizationOptions.alert.rawValue | JPAuthorizationOptions.badge.rawValue | JPAuthorizationOptions.sound.rawValue)
  7.  
  8. JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)
  9.  
  10. // 初始化JUSH
  11. JPUSHService.setup(withOption: launchOptions, appKey: "b29ccf03d1e6aca9baa3c34a", channel: "App Store", apsForProduction: false)
  12.  
  13. return true
  14. }
  15.  
  16. /// 获取DeviceToken
  17. func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  18. JPUSHService.registerDeviceToken(deviceToken)
  19. }
  20.  
  21. /// 注册失败
  22. func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
  23. print(error)
  24. }

2.设置代理,处理通知

 
  1. extension AppDelegate : JPUSHRegisterDelegate {
  2.  
  3. /// 获取通知
  4. func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {
  5.  
  6. }
  7.  
  8. /// 可设置在前台获取通知
  9. func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {
  10.  
  11.  
  12. let userInfo = notification.request.content.userInfo
  13.  
  14. let isPushTrigger = notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self) ?? false
  15.  
  16. if isPushTrigger {
  17. JPUSHService.handleRemoteNotification(userInfo)
  18.  
  19. }
  20.  
  21. let value = Int(UNNotificationPresentationOptions.alert.rawValue | UNNotificationPresentationOptions.sound.rawValue | UNNotificationPresentationOptions.badge.rawValue)
  22.  
  23. completionHandler(value)
  24. // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
  25. }
  26. }

 

 

//原文:http://bbs.520it.com/forum.php?mod=viewthread&tid=3020

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!