iOS推送通知学习与总结

这篇文章整理iOS10之前的推送通知(文中的推送通知,如不做特殊说明,默认是iOS10以前的推送通知)

iOS10以后的推送通知,请看这篇


  • 本地推送通知:

本地推送通知是开发人员在APP内部发送,即使没有联网也能收到的推送.
应用场景是提醒某个时刻用户该干啥.
通知发出时,如果程序正在运行在前台,那么推送就不会被呈现(但仍然是收到的)
不管APP打开还是关闭,推送通知都会如期发出

二话不说,先发一个通知,然后再来介绍每个步骤:
  • 首先申请推送权限(iOS8.0之后需要申请权限)
  let type = UIUserNotificationType.alert.rawValue | UIUserNotificationType.badge.rawValue | UIUserNotificationType.sound.rawValue
  let sets = UIUserNotificationSettings(types: UIUserNotificationType(rawValue : type), categories: nil)
  UIApplication.shared.registerUserNotificationSettings(sets)
  • 创建一个通知:
  //创建一个通知
  let localNot = UILocalNotification()
  //设置通知的必选项   
  localNot.alertBody = "我是通知"   
  //通知的发送时间    
  localNot.fireDate = NSDate(timeIntervalSinceNow: 2) as Date
  • 发送这个通知:
  //1:立即发送 : 
  UIApplication.shared.presentLocalNotificationNow(localNot)
  //2:按照规定时间发送:
  UIApplication.shared.scheduleLocalNotification(localNot)

经过三个步骤,本地通知就已经发送完毕
需要把APP退到后台,或者杀死才能看到通知
alertBody就是要显示的内容

  • 效果图:


    iOS推送通知学习与总结_第1张图片
    效果图.png
  • 另外本地推送通知还有一些额外设置:

  //重复发送的时间周期
  localNot.repeatInterval = NSCalendar.Unit.minute
  //设置锁屏滑动文字(显示效果为:滑动来回复)
  //如果不设置该属性,则显示:滑动来查看
  localNot.alertAction = "回复"
  //标题:iOS8.2以后才有
  if #available(iOS 8.2, *) {
        localNot.alertTitle = "斗地主"
  }
  // 设置通知的声音
  localNot.soundName = "win.aac"
  // 设置图标右上角的数字(0 代表不显示)
  localNot.applicationIconBadgeNumber = 10
当收到本地通知后,需要做推送的监听

APP的状态不同,监听方式不同:

  • 当app关闭时
    点击收到的通知进入app时launchOptions中UIApplicationLaunchOptionsKey.localNotification对应的值不为空:
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {        
        //launchOptions: 只要不是正常启动(点击图标启动),这个字典就部位空
        if launchOptions != nil {
            let local = launchOptions![UIApplicationLaunchOptionsKey.localNotification]
            if local != nil {
                //业务处理
            }
        }
        return true
    }
  • 当app在前台或后台时
    当app在前台时收到通知走这个方法(在前台时,虽然收到但是并不显示通知)
    当app在后台收到通知,点击通知,走这个方法
    func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        let state = UIApplication.shared.applicationState
        if state == UIApplicationState.active {//如果在前台
            //业务处理
        }else if state == UIApplicationState.inactive{//如果在后台
            //业务处理
        }
    }
监听本地推送的额外操作

收到通知时,可以下拉通知,在不打开app的情况下,快捷回复
效果图:


iOS推送通知学习与总结_第2张图片
下拉通知,显示操作

iOS推送通知学习与总结_第3张图片
点击回复,弹出键盘
  • 额外操作按钮以组的形式存放在categories中,在申请通知权限的时候创建并添加
        //创建一组操作行为
        let category : UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
        //设置行为标识
        category.identifier = "select"
        //添加操作行为1
        let action1 = UIMutableUserNotificationAction()
        action1.identifier = "buli"
        action1.title = "不理"
        //在前台执行
        action1.activationMode = UIUserNotificationActivationMode.foreground
        //是否需要解锁
        action1.isAuthenticationRequired = true
        //添加操作行为2
        let action2 = UIMutableUserNotificationAction()
        action2.identifier = "huifu"
        action2.title = "回复"
        //显示输入框(支持iOS9.0以后)
        if #available(iOS 9.0, *) {
            action2.behavior = UIUserNotificationActionBehavior.textInput
            action2.parameters = [UIUserNotificationTextInputActionButtonTitleKey : "走你"]
        }
        action1.activationMode = UIUserNotificationActivationMode.background
        action1.isAuthenticationRequired = false
        
        let actions = [action1, action2]
        //default:默认两个action
        category.setActions(actions, for: UIUserNotificationActionContext.default)
        let categories : Set = [category]
        //在申请通知权限的时候,加入已经创建好的操作组
        let type = UIUserNotificationType.alert.rawValue | UIUserNotificationType.badge.rawValue | UIUserNotificationType.sound.rawValue
        let sets = UIUserNotificationSettings(types: UIUserNotificationType(rawValue : type), categories: categories)
        UIApplication.shared.registerUserNotificationSettings(sets)
  • 然后在发送通知的时候,绑定category(category.identifier = "select" 是操作的唯一标识))
       let localNot = UILocalNotification()
       localNot.category = "select"
  • 点击category中按钮的监听
    //iOS8.0
    func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -> Void) {
        print(identifier!)
        completionHandler()
    }
    //iOS9.0(可以拿到输入框中输入的内容)
    func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
        print(identifier!, responseInfo)
        completionHandler()
    }

  • 远程通知

远程推送是我们的手机和苹果的服务器建立了长连接
在联网的状态下
能收到苹果服务器发送的推送消息
即使我们的APP是关闭的状态.
调试远程推送需要在真机进行测试
并且安装推送证书
服务端可以用PushMeBaby代替,附赠下载链接:
链接: https://pan.baidu.com/s/1i506gGd 密码: r2fe
下载证书(不再赘述)后开始敲代码:

注册通知:
  • 首先打开这个开关:


    打开开关
  • 然后是注册代码:
        //iOS8以后
        let type = UIUserNotificationType.alert.rawValue | UIUserNotificationType.badge.rawValue
        let set = UIUserNotificationSettings(types: UIUserNotificationType(rawValue : type), categories: nil)
        //注册通知
        UIApplication.shared.registerUserNotificationSettings(set)
        //注册远程通知获取deviceToken
        UIApplication.shared.registerForRemoteNotifications()
  • 注册远程通知后,拿到deviceToken
    //获取成功
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print(deviceToken as NSData)
    }
    //获取失败(没联网,或者没有打开开关)
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("注册失败")
    }
  • deviceToken大概是这样:

  • 把下载的证书拖到PushMeBaby中去改好名字如图:


    iOS推送通知学习与总结_第4张图片
    PushMeBaby所需证书.png
  • 运行PushMeBaby,把打印的deviceToken复制进去:


    iOS推送通知学习与总结_第5张图片
    如图.png
  • 点击push,就能收到推送啦:


    iOS推送通知学习与总结_第6张图片
    收到推送
远程通知的监听
    //iOS3.0以后的方法,基本不用
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
        print("收到推送")
    }
    
    //iOS7.0以后
    //以下情况 收到通知会走这个方法:
    //在前台
    //在后台
    //完全退出时
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("收到推送")
        //系统要求在最后需要调用,进行计时和更新缩略图等操作
        completionHandler(UIBackgroundFetchResult.newData)
    }
  • 推送内容的格式
{
    "aps": {
        "alert": "这是远程推送",
        "badge": 1,
        "content-available": "xx"
    }
}
//content-available:如果加上这个字段,在收到通知的那一刻,就会执行这个方法,无论是否点击通知:
  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
(没有这个字段的话,只有APP在前台的时候,收到通知才会走这个方法,在后台或者挂掉的时候收到通知,只有点击通知才会走这个方法)

对于远程通知添加Category额外操作,和本文前面写的本地通知的方式一样,不再赘述.

本文Demo:

本地通知
远程通知
写的匆忙,若有错误,还请指教

感谢阅读
你的支持是我写作的唯一动力

关注我的文章微信公众号, 王技术与你同在

iOS推送通知学习与总结_第7张图片
扫码关注我.jpg

你可能感兴趣的:(iOS推送通知学习与总结)