美文网首页QiShare文章汇总Swift学习
用Swift5.1实现iOS中的远程推送流程

用Swift5.1实现iOS中的远程推送流程

作者: QiShare | 来源:发表于2019-08-15 13:29 被阅读29次

    级别: ★★☆☆☆
    标签:「iOS」「Swift 」「Push」
    作者: dac_1033
    审校: QiShare团队


    我们之前发过关于推送的文章iOS 推送通知及通知扩展,其中介绍了推送相关流程及代码实现,不过使用OC实现的,现在我们就来介绍一下在iOS10.0以上系统中,用Swift处理远程推送通知的相关流程及实现。

    1. 远程推送的流程

    苹果官方提供的远程推送通知的传递示意图如下:

    远程推送通知的传递过程

    各关键组件之间的交互细节:

    各关键组件之间的交互细节

    不论实现的语言是OC该是Swift,远程推送流程都是一样的,只是根据iOS版本的不同,注册推送的方法、收到推送是的回调方法会有不同。

    2. 实现远程推送功能的准备工作

    • 在开发者账号中,创建AppID,并为AppID开通推送权限;
    • 生成并下载安装推送证书、描述文件;
    • APP端的工程设置界面,capabilities页面下,将“Push Notifications”设置为ON。

    3. 不同iOS版本间推送通知的区别

    • aps串的格式变化
    // iOS10.0 之前: 
    {"aps":{"alert":{"body": "This is a message"},"sound":"default","badge":1}}
    //iOS 10 基础Payload:
    {"aps":{"alert":{"title":"I am title","subtitle":"I am subtitle","body":"I am body"},"sound":"default","badge":1}}
    
    • 注册通知
      iOS10.0 之前
    //iOS8以下 
    [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
    //iOS8 - iOS10
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
    

    iOS10.0 及以后

    // OC
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    UNAuthorizationOptions options = UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert;
    [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
    
    }
    
    // Swift
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]{          granted, error in
    }
    
    • 获取推送设置
      iOS10.0 之前是不能获取推送设置的,iOS 10 还可以实时获取用户当前的推送的设置信息:
    @available(iOS 10.0, *)
    open class UNNotificationSettings : NSObject, NSCopying, NSSecureCoding {
    
        open var authorizationStatus: UNAuthorizationStatus { get }
        open var soundSetting: UNNotificationSetting { get }
        open var badgeSetting: UNNotificationSetting { get }
        open var alertSetting: UNNotificationSetting { get }
        open var notificationCenterSetting: UNNotificationSetting { get }
        open var lockScreenSetting: UNNotificationSetting { get }
        open var carPlaySetting: UNNotificationSetting { get }
        open var alertStyle: UNAlertStyle { get }
    }
    
    //获取设置
    UNUserNotificationCenter.current().getNotificationSettings {
        settings in 
        print(settings.authorizationStatus) // .authorized | .denied | .notDetermined
        print(settings.badgeSetting) // .enabled | .disabled | .notSupported
    }
    

    2 UserNotifications

    iOS10.0 及之后iOS加入了UserNotifications框架,Swift中的这个框架包括了以下库:

    import UserNotifications.NSString_UserNotifications
    import UserNotifications.UNError
    import UserNotifications.UNNotification
    import UserNotifications.UNNotificationAction
    import UserNotifications.UNNotificationAttachment
    import UserNotifications.UNNotificationCategory
    import UserNotifications.UNNotificationContent
    import UserNotifications.UNNotificationRequest
    import UserNotifications.UNNotificationResponse
    import UserNotifications.UNNotificationServiceExtension
    import UserNotifications.UNNotificationSettings
    import UserNotifications.UNNotificationSound
    import UserNotifications.UNNotificationTrigger
    import UserNotifications.UNUserNotificationCenter
    

    3. 需要实现的代码

    • 注册远程推送
      要先导入UserNotifications头文件,注册逻辑如下:
    // 在AppDelegate的didFinishLaunchingWithOptions方法中注册远程推送通知
    // - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
    
    // 注册远程推送通知
    func registerNotifications(_ application: UIApplication) {
            
            if #available(iOS 10.0, *) {
                let center = UNUserNotificationCenter.current()
                center.delegate = self
                center.getNotificationSettings { (setting) in
                    if setting.authorizationStatus == .notDetermined {
                        center.requestAuthorization(options: [.badge,.sound,.alert]) { (result, error) in
                            if(result){
                                if !(error != nil){
                                    // 注册成功
                                    DispatchQueue.main.async {
                                        application.registerForRemoteNotifications()
                                    }
                                }
                            } else{
                                //用户不允许推送
                            }
                        }
                    } else if (setting.authorizationStatus == .denied){
                        // 申请用户权限被拒
                    } else if (setting.authorizationStatus == .authorized){
                        // 用户已授权(再次获取dt)
                        DispatchQueue.main.async {
                            application.registerForRemoteNotifications()
                        }
                    } else {
                        // 未知错误
                    }
                }
            }
        }
    
    • 处理deviceToken:
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      
      let dtDataStr = NSData.init(data: deviceToken)
      let dtStr = dtDataStr.description.replacingOccurrences(of: "<", with: "").replacingOccurrences(of: ">", with: "").replacingOccurrences(of: " ", with: "")
     // 上报deviceToken
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            
       // 弹窗提示
    }
    
    • 处理接收到的推送信息:
    // UNUserNotificationCenterDelegate
    
    // The method will be called on the delegate only if the application is in the foreground. 
    // If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. 
    // The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. 
    // This decision should be based on whether the information in the notification is otherwise visible to the user.
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.14);
    
    // The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. 
    // The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.14) __TVOS_PROHIBITED;
    
    // The method will be called on the delegate when the application is launched in response to the user's request to view in-app notification settings. 
    // Add UNAuthorizationOptionProvidesAppNotificationSettings as an option in requestAuthorizationWithOptions:completionHandler: to add a button to inline notification settings view and the notification settings view in Settings. 
    // The notification will be nil when opened from Settings.
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(nullable UNNotification *)notification __IOS_AVAILABLE(12.0) __OSX_AVAILABLE(10.14) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
    

    写好代码并设置好证书后,可以使用测试工具Pusher和真机测试一下...


    小编微信:可加并拉入《QiShare技术交流群》。

    关注我们的途径有:
    QiShare(简书)
    QiShare(掘金)
    QiShare(知乎)
    QiShare(GitHub)
    QiShare(CocoaChina)
    QiShare(StackOverflow)
    QiShare(微信公众号)

    推荐文章:
    iOS UI状态保存和恢复(三)
    iOS UI状态保存和恢复(二)
    iOS UI状态保存和恢复(一)
    Swift 运算符
    iOS 中精确定时的常用方法
    Dart基础(一)
    Dart基础(二)
    Dart基础(三)
    Dart基础(四)
    奇舞周刊

    相关文章

      网友评论

        本文标题:用Swift5.1实现iOS中的远程推送流程

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