用Swift5.1實現iOS中的遠程推送流程

級別: ★★☆☆☆
標籤:「iOS」「Swift 」「Push」
做者: dac_1033
審校: QiShare團隊php


咱們以前發過關於推送的文章iOS 推送通知及通知擴展,其中介紹了推送相關流程及代碼實現,不過使用OC實現的,如今咱們就來介紹一下在iOS10.0以上系統中,用Swift處理遠程推送通知的相關流程及實現。git

1. 遠程推送的流程

蘋果官方提供的遠程推送通知的傳遞示意圖以下:github

遠程推送通知的傳遞過程

各關鍵組件之間的交互細節:bash

各關鍵組件之間的交互細節

不論實現的語言是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 及之後app

// 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和真機測試一下...async


小編微信:可加並拉入《QiShare技術交流羣》。ide

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)工具

推薦文章:
iOS UI狀態保存和恢復(三)
iOS UI狀態保存和恢復(二)
iOS UI狀態保存和恢復(一)
Swift 運算符
iOS 中精肯定時的經常使用方法
Dart基礎(一)
Dart基礎(二)
Dart基礎(三)
Dart基礎(四)
奇舞週刊

相關文章
相關標籤/搜索