Swift原生推送(APNS)适配

  • 推送的基本适配
//ios10.0以后
 if #available(iOS 10.0, *){
            let notifiCenter = UNUserNotificationCenter.current()
            notifiCenter.delegate = self
            notifiCenter.requestAuthorization(options: [.alert,.sound,.badge]) { (accepted, error) in

                if !accepted {
                    print("用户不允许消息通知。")
                }
            }
        
            UIApplication.shared.registerForRemoteNotifications()
       //ios8.0以后
        }else if #available(iOS 8.0, *){  
        
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: UIUserNotificationType(rawValue: UIUserNotificationType.alert.rawValue | UIUserNotificationType.sound.rawValue | UIUserNotificationType.badge.rawValue), categories: nil))
            UIApplication.shared.registerForRemoteNotifications()
        }else{    //其他
            
            let type = UIRemoteNotificationType(rawValue: UIRemoteNotificationType.alert.rawValue | UIRemoteNotificationType.badge.rawValue | UIRemoteNotificationType.sound.rawValue)
            UIApplication.shared.registerForRemoteNotifications(matching: type)
        }
  • 获取deviceToken上传服务器
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print(deviceToken.map { String(format: "%02hhx", $0) }.joined())
    }
  • 接收到推送后调用方法对通知进行处理
 //iOS10新增:处理前台收到通知的代理方法
    @available(iOS 10.0, *)
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void){
        let userInfo = notification.request.content.userInfo
        print("userInfo10:\(userInfo)")
        completionHandler([.sound,.alert])
        
    }
    
    //iOS10新增:处理后台点击通知的代理方法
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void){
        let userInfo = response.notification.request.content.userInfo
        print("userInfo10:\(userInfo)")
        completionHandler()
    }
    
    private func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("收到新消息Active\(userInfo)")
        if application.applicationState == UIApplicationState.active {
            // 代表从前台接受消息app
        }else{
            // 代表从后台接受消息后进入app
            UIApplication.shared.applicationIconBadgeNumber = 0
        }
        completionHandler(.newData)
        
    }
  • iOS9.0以后deviceToken在删除app再重新获取时会改变,会导致很多后续问题,具体问题和处理方法如下:
1.可能出现的问题:

使同一设备对应了多个deviceToken,设备接收推送时一个推送接收多次,删除后重新下载后deviceToken改变,之前的deviceToken失效,新的deviceToken才会重新接收推送等等

2.解决办法

首次进入app获取deviceToken,用户登录token一并发送服务器进行保存,本地保存一份,当再次获取到deviceToken时和本地进行比较,改变了就告诉服务器对应登录的token的deviceToken改变,让服务器删除之前的,保留最新的,如果没改变就不做处理。
如果存在游客模式下的推送,上面的方法显然不能满足,这时可以获取到设备的uuid和deviceToken进行上传服务器,进行服务器和本地保存,这样如果deviceToken改变,就可以根据uuid找到对应设备上的deviceToken进行重新绑定。

你可能感兴趣的:(Swift原生推送(APNS)适配)