遠程推送ios9&ios10

關于遠程推送的原理可以參考這篇博客:
http://blog.tingyun.com/web/article/detail/571

模擬遠程推送的工具:
https://github.com/stefanhafeneger/PushMeBaby
https://github.com/noodlewerk/NWPusher

ios8.0遠程推送負載內(nèi)容

內(nèi)容格式必要要知道的啊,服務端一般會要我們客戶端定義好格式給他們的。

每一條通知的消息都會組成一個JSON字典對象,其格式如下所示,示例中的key值為蘋果官方所用key。自定義字段的時候要避開這些key值。
{
     "aps" : {  
         "alert"              :              {   // string or dictionary
            "title"          :   "string"
            "body"           :   "string",
            "title-loc-key"  :   "string or null"
            "title-loc-args" :   "array of strings or null"
            "action-loc-key" :   "string or null"
            "loc-key"        :   "string"
            "loc-args"       :   "array of strings"
            "launch-image"   :   "string"
         },
          "badge"             :    number,
          "sound"             :    "string"
          "content-available" :    number;
          "category"          :    "string"
     },
}

aps:推送消息必須有的key

alert:推送消息包含此key值,系統(tǒng)就會根據(jù)用戶的設置展示標準的推送信息
badge:在app圖標上顯示消息數(shù)量,缺少此key值,消息數(shù)量就不會改變,消除標記時把此key對應的value設置為0
sound:設置推送聲音的key值,系統(tǒng)默認提示聲音對應的value值為default
content-available:此key值設置為1,系統(tǒng)接收到推送消息時就會調(diào)用不同的回調(diào)方法,iOS7之后配置后臺模式
category:UIMutableUserNotificationCategory's identifier 可操作通知類型的key值

title:簡短描述此調(diào)推送消息的目的,適用系統(tǒng)iOS8.2之后版本
body:推送的內(nèi)容
title-loc-key:功能類似title,附加功能是國際化,適用系統(tǒng)iOS8.2之后版本
title-loc-args:配合title-loc-key字段使用,適用系統(tǒng)iOS8.2之后版本
action-loc-key:可操作通知類型key值,不詳細敘述
loc-key:參考title-loc-key
loc-args:參考title-loc-args
launch-image:點擊推送消息或者移動事件滑塊時,顯示的圖片。如果缺少此key值,會加載app默認的啟動圖片。
當然以上key值并不是每條推送消息都必帶的key值,應當根據(jù)需求來選擇所需要的key值,除了以上系統(tǒng)所提供的key值外,你還可以自定義自己的key值,來作為消息推送的負載,自定義key值與aps此key值并列。如下格式:

{
    "aps" : {
        "alert" : "Provider push messag.",
        "badge" : 9,
        "sound" : "toAlice.aiff"
    },
    "Id"   : 1314,               //  自定義key值
    "type" : "customType"        //  自定義key值
}
{
ios10.0
{
  "aps" : {
    "alert" : {
      "title" : "iOS遠程消息,我是主標題!-title",
      "subtitle" : "iOS遠程消息,我是主標題!-Subtitle",
      "body" : "Dely,why am i so handsome -body"
    },
    "category" : "alert",
    "badge" : "2"
  }
}

<h1>一、ios8的遠程推送

        // 遠程推送APNs必須使用真機調(diào)試,并且必須使用付費的開發(fā)者賬號配置好對應的bundle ID和真機推送證書

        UIApplication.shared.registerForRemoteNotifications()
      
        let acceptAction = UIMutableUserNotificationAction()
        acceptAction.identifier = "acceptAction"
        acceptAction.title = "接受"
        acceptAction.activationMode = .foreground
        acceptAction.isDestructive = true
        
        //拒絕按鈕
        let rejectAction = UIMutableUserNotificationAction()
        rejectAction.identifier = "rejectAction"
        rejectAction.title = "拒絕"
        rejectAction.activationMode = .background
        rejectAction.isAuthenticationRequired = true //需要解鎖才能處理
        rejectAction.isDestructive = true
        
        //輸入按鈕
        let inputAction = UIMutableUserNotificationAction()
        inputAction.behavior = .textInput
        inputAction.title = "輸入"
        inputAction.identifier = "textInput"
        inputAction.isDestructive = false
        inputAction.activationMode = .background
        
        let categorys = UIMutableUserNotificationCategory()
        categorys.identifier = "alert"
        let actions = [acceptAction,rejectAction,inputAction]
        
        categorys.setActions(actions, for: .default)
        var set = Set<UIMutableUserNotificationCategory>()
        set.insert(categorys)
        let repeatSettings = UIUserNotificationSettings(types: [.alert,.badge,.sound], categories: set)
        UIApplication.shared.registerUserNotificationSettings(repeatSettings)

    //獲取DeviceToken成功
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        //Swift中獲取deviceToken
        //http://stackoverflow.com/questions/9372815/how-can-i-convert-my-device-token-nsdata-into-an-nsstring
        var token: String = ""
        for i in 0..<deviceToken.count {
            token += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
        }
        
        print(token)
    }

  //獲取DeviceToken失敗
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        
    }

1.用戶點擊通知會調(diào)用的方法

  //MARK: ios 8.0之后點擊橫幅會調(diào)用的方法
// ----------------------------------------------------------------------------
// 監(jiān)聽遠程推送通知點擊(優(yōu)先級較低),接收到通知,用戶點擊進入才會調(diào)用該方法
 當接收到推送通知之后, 并且滿足一下條件
 app 在前臺時 ,會調(diào)用該方法
 app 從后臺進入到前臺 (App一開始在后臺, app 鎖屏),點擊通知會調(diào)用該方法
 app 完全退出
 如果app 完全退出, 這時候,如果用戶點擊通知, 打開APP , 不會調(diào)用這個方法
 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
     print(userInfo)
     UIApplication.shared.applicationIconBadgeNumber = 10
     completionHandler(.newData)
  }

2.一接收到通知就會立即調(diào)用該方法
效果: 當用戶收到通知之后, 即使沒有點擊也會調(diào)用這個方法
條件:
1.需要勾選后臺模式 remote notification,在后臺
2.必須保證發(fā)送的推送通知格式, 包括 "content-available":"隨便傳"
3.執(zhí)行completionHandler 回調(diào)代碼塊

// ----------------------------------------------------------------------------
// 監(jiān)聽遠程推送通知點擊(優(yōu)先級較高),一接收到通知就會立即調(diào)用該方法
    當接收到推送通知之后, 并且滿足一下條件
    當我們實現(xiàn), 這個方法時, 上面一個方法不再執(zhí)行
    計時APP 完全退出, 也會調(diào)用這個方法
    completionHandler : 統(tǒng)計我們處理的時間, 耗電量, 刷新預覽圖片
    {"aps" :
        {
            "alert" : "This is some fancy message.",
            "badge":1,
            "content-available":"隨便傳"
        }
    }
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;

執(zhí)行completionHandler 作用

1> 系統(tǒng)會估量App消耗的電量,并根據(jù)傳遞的UIBackgroundFetchResult 參數(shù)記錄新數(shù)據(jù)是否可用
2> 調(diào)用完成的處理代碼時,應用的界面縮略圖會自動更新

如果想要接收到通知后,不要用戶點擊通知, 就執(zhí)行以下代碼, 那么必須有三個要求:
1> 必須勾選后臺模式Remote Notification ;
2> 告訴系統(tǒng)是否有新的內(nèi)容更新(執(zhí)行完成代碼塊)
3> 服務器發(fā)送通知的格式必須要有content-available字段("content-available":"隨便傳")

<h1>二、ios10的遠程推送

注冊通知:
        UIApplication.shared.registerForRemoteNotifications()
        
        let action1 = UNNotificationAction(identifier: "action1", title: "接受邀請", options: .authenticationRequired)
        let action2 = UNNotificationAction(identifier: "action2", title: "查看邀請", options: .foreground)
        let action3 = UNNotificationAction(identifier: "action3", title: "取消", options: .destructive)
        let action4 = UNTextInputNotificationAction(identifier: "action4", title: "輸入", options: .foreground, textInputButtonTitle: "發(fā)送", textInputPlaceholder: "tell me loudly")
        let category1 = UNNotificationCategory(identifier: "alert", actions: [action1,action2,action3,action4], intentIdentifiers: [], options: .customDismissAction)
        
        var set = Set<UNNotificationCategory>()
        set.insert(category1)
        center.setNotificationCategories(set)

  //MARK: ios10 收到通知(本地和遠端)
    /*
     蘋果把本地通知跟遠程通知合二為一。區(qū)分本地通知跟遠程通知的類是UNPushNotificationTrigger.h類中,UNPushNotificationTrigger的類型是新增加的,通過它,我們可以得到一些通知的觸發(fā)條件 ,解釋如下:
     
     UNPushNotificationTrigger (遠程通知) 遠程推送的通知類型
     UNTimeIntervalNotificationTrigger (本地通知) 一定時間之后,重復或者不重復推送通知。我們可以設置timeInterval(時間間隔)和repeats(是否重復)。
     UNCalendarNotificationTrigger(本地通知) 一定日期之后,重復或者不重復推送通知 例如,你每天8點推送一個通知,只要dateComponents為8,如果你想每天8點都推送這個通知,只要repeats為YES就可以了。
     UNLocationNotificationTrigger (本地通知)地理位置的一種通知,
     當用戶進入或離開一個地理區(qū)域來通知。
     現(xiàn)在先提出來,后面我會一一代碼演示出每種用法。還是回到兩個很吊的代理方法吧

     */
    //MARK: App處于前臺接收通知時
    /*
        1.下面這個代理方法,只會是app處于前臺狀態(tài) 前臺狀態(tài) and 前臺狀態(tài)下才會走,后臺模式下是不會走這里的
     */
    public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Swift.Void) {
        
        if notification.request.trigger is UNPushNotificationTrigger {
            //遠程通知
            print("ios10.0 遠程通知")
        }else {
            //本地通知
            print("ios10.0 收到本地通知")
        }
        
        completionHandler([.badge,.sound,.alert])
        /*
         4.不管前臺后臺狀態(tài)下。推送消息的橫幅都可以展示出來!后臺狀態(tài)不用說,前臺時需要在前臺代理方法中設置 ,設置如下:
         // 需要執(zhí)行這個方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以設置
         */
    }
    
    
    // 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 applicationDidFinishLaunching:.
    //App通知的點擊事件
    /*
        2.下面這個代理方法,只會是用戶點擊消息才會觸發(fā),如果使用戶長按(3DTouch)、彈出Action頁面等并不會觸發(fā)。點擊Action的時候會觸發(fā)!
     */
    public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void){
        UIApplication.shared.applicationIconBadgeNumber = 10
        if response.notification.request.trigger is UNPushNotificationTrigger {
            if response.actionIdentifier == "action4" {
                let userSayStr = (response as? UNTextInputNotificationResponse)?.userText
                print("輸入:\(userSayStr)")
            }else if response.actionIdentifier == "action3" {
                print("取消")
            }else if response.actionIdentifier == "action2"{
                print("看看邀請")
            }else if response.actionIdentifier == "action1" {
                print("接受邀請")
            }
        }else {
            print("ios10 本地通知")
        }
        
        completionHandler()
        /*
         3.點擊代理最后需要執(zhí)行:completionHandler(); // 系統(tǒng)要求執(zhí)行這個方法
         不然會報:
         2016-09-27 14:42:16.353978 UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
         */
    }

參考文章:
http://www.itdecent.cn/p/c623c2b5966a
http://www.itdecent.cn/p/4b947569a548
http://www.itdecent.cn/p/c58f8322a278
http://www.itdecent.cn/p/81c6bd16c7ac
https://onevcat.com/2016/08/notification/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容