iOS Notification – 遠程通知

本文講解iOS的遠程通知的基本使用,主要包括遠程通知的類型,處理遠程通知的場景,以及遠程通知相關證書的配置等等。

一、APNs簡介

        APNs是蘋果公司提供的遠程通知的服務器,當App處於後臺或者沒有運行時,如果後臺需要發送通知,那麼就需要藉助APNs服務器。在App接收通知的過程中,通知的發送路徑是:

Provider -> APNs服務器 -> iPhone -> App

其中,ProviderAPNs之間有一個TLS連接,Provider通過該連接將遠程通知發送到APNs服務器;iPhoneAPNs之間也有一個TLS連接,APNs將遠程通知通過該連接發送給iPhone,進而通知用戶某App有新通知。

iPhoneAPNs連接圖如下:

圖片1

注意:

  • 此連接由系統建立並維持,無需開發人員管理;
  • 上圖中的證書是蘋果設備本身的證書,與開發者賬號中申請的證書無關;
  • 每個設備與 APNs 服務器只需維持一條連接。

ProviderAPNs連接圖如下:

圖片2

注意:

  • 此連接由 Appbundle ID 唯一確定
  • 上圖中 Provider certificate 需要通過開發者賬號申請生成,其中包含 Appbundle ID

APNs工作流程

圖片3

注意:

  • 首先客戶端需要向 APNs 服務器註冊當前 AppAPNs 會返回一個 Token(注意這個過程要求App有合法的證書,需要包含推送功能的證書);注意不同應用在同一設備上獲取的 Token不同,同一應用在不同設備上獲取的 Token也不同,所以 Token 是跟設備與 App 唯一綁定的
  • App 拿到 Token 後需要將其發送給 Provider
  • Provider 發送推送通知時,指定 Token 和通知內容,併發送給 APNs 服務器
  • APNs 服務器會將通知發送給 Token 對應的設備上
  • 設備收到通知後,根據 APNs 發過來的通知中帶有的 bundle ID 信息區分是哪個App的遠程通知(這裏應該是根據 Token 來獲取 bundle ID)

APNs的Feedback 機制

FeedbackAPNs 服務器提供的用於減少服務器壓力以及優化網絡的服務,工作流程圖如下:

圖片4

注意:

  • Provider 發送一個遠程通知給 APNs 服務器,APNs 服務器會檢測目的設備是否在線,如果不在線,那麼 APNs 服務器會暫存該消息
  • 當目的設備上線後,APNs 會發送暫存的消息給目的設備(按照蘋果官方說法暫存消息只會暫存最後一條消息,之前的消息會被丟棄);
  • 如果目的設備很久都沒有上線,那麼 APNs 消息會把該設備加入 feedback 名單。Provider 可以定期去 APNs 拉新 feedback 名單;
  • Provider 再次給之前的設備發送遠程通知時,需要檢查一下 feedback 名單,如果設備在這個名單,則不再發送給 APNs 了;
  • 當設備重新上線後,Provider 可以再將此設備移除feedback 名單,當 Provider 更新 feedback list 後,就可以重新給該設備發送遠程通知了。當然,feedback list 的更新可能會有周期,如果需要及時有效的更新 feedback list,那麼需要 App 打開後,及時通知 Provider
  • 這種機制的好處就是防止發送多餘無用的遠程通知消息,一方面可以減緩 APNs 服務器的壓力,另一方面也可以減少網絡流量

二、證書配置

假定已經有開發證書的情況,下面只介紹配置推送證書的步驟

  1. 創建新的App ID
  2. 創建推送證書和發佈證書
  3. 創建新的Provisioning Profiles

三、通知類型

        遠程通知具體可分爲普通遠程通知靜默遠程通知

普通遠程通知

收到通知後,有文字和聲音,點擊通知會進入App,然後執行如下方法

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

靜默遠程通知

收到通知後,沒有文字和聲音,不用點開通知,也不用打開App,就能執行如下方法

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

靜默通知注意點:

  • aps數據中一定要加"content-available" : 1
  • 一定不能加alert,如果加入了alert就不是靜默推送了
  • soundbadge也不能加

四、通知處理場景

1.申請通知權限

    if (DEF_IOS10) {
        // iOS 10
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center requestAuthorizationWithOptions:UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"greet");
            } else {
                NSLog(@"reject");
            }
        }];
    } else if (DEF_IOS8) {
        // iOS 8 和 iOS 9
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    } else {
        // iOS 7
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound];
    }

iOS9以後,每次重新安裝應用後得到的 Token 是不一樣的,而且每次重裝系統也會改變,所以 每次應用啓動時都需要按上面的步驟註冊一次

2.發送DeviceToken

application:didRegisterForRemoteNotificationsWithDeviceToken:

在這個方法裏把deviceToken發送給服務器Provider

3.接收通知

** 應用在前臺

iOS6


-(void) application: didReceiveRemoteNotification:

iOS7 ~ iOS9


-(void) application: didReceiveRemoteNotification: fetchCompletionHandler:

iOS10


-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler

** 應用在後臺,但是還活着

iOS6 ~ iOS9 調用方法和應用在前臺相同

iOS10


-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler

** 應用被殺死狀態

這種情況和應用重新啓動類似,應用會調用下面的方法重新啓動

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

其中,通知的信息在launchOptions裏,

id userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]

參考資料

http://www.jianshu.com/p/ad43bc1a970a

http://www.tuicool.com/articles/AFRvemV

http://blog.csdn.net/hherima/article/details/47133171

圖片來自互聯網,如有侵權,請聯繫作者,我怕賠不起……

發佈了49 篇原創文章 · 獲贊 16 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章