極光推送的使用


極光推送的使用

 

蘋果的APNS

image.png
  1. 用戶的應用注冊了APNS 消息推送功能
  2. 用戶iOS設備通過SSL長連接到APNS蘋果服務器,收到設備應用的注冊信息后,下發給設備一個DeviceToken 給 應用
  3. 應用收到這個DeviceToken 然后推送給 自己應用的服務器 (應用到推送服務器的流程完畢)
  4. 推送服務器 發送消息到一個用戶的時候, 會首先查找到 DeviceToken,然后將消息和DeviceToken 發送給 蘋果的 APNS 服務器
  5. 蘋果根據 DeviceToken 找到唯一的那台設備, 然后將消息 傳遞過去
  6. 設備收到了消息后, 會根據DeviceToken 找到應用 (推送服務器到設備應用的流程完畢)

極光推送的流程

極光推送

這里和上面唯一不同的就是, 應用的服務器改為了 極光的服務器

  1. 設備獲取到DeviceToken 后 需要將這個 信息 上傳到 極光的 服務器上面
  2. 然后 極光的服務器會 生成一個registrationID給應用
  3. 這個時候, 我們可以給應用注冊一個別名, 就相當於一個 鍵值對, 極光服務器根據這個別名查找到registrationID, 然后又根據registrationID找到 DeviceToken, 這樣 發送消息的時候 , 就可以將 DeviceToken 和 信息一起發送給 蘋果的APNS服務器了.

實際編程的注意點

image.png

1、極光后台的生成環境和發布環境證書必須有效

 

image.png

 

2、 應用需要先注冊和激活極光服務

image.png
  1. 應用獲取到APNS下發的DeviceToken后,需要上傳到極光服務器
  2. 應用的極光登錄成功方法回調,說明服務器已經收到的應用的設備信息,並且返回了registrationID
  3. 只有在registrationID返回之后,才可以設置別名

補充信息

kJPFNetworkDidLoginNotification

uid:939xxx3544 
registrationID:141fe1daxxx927a72d

代碼中方法的調用順序 , 一定要嚴格按照如下的順序

1、添加初始化APNs代碼添加初始化APNs代碼

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions //Required //notice: 3.0.0及以后版本注冊可以這樣寫,也可以繼續用之前的注冊方式 JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init]; entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound; if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { // 可以添加自定義categories // NSSet<UNNotificationCategory *> *categories for iOS10 or later // NSSet<UIUserNotificationCategory *> *categories for iOS8 and iOS9 } [JPUSHService registerForRemoteNotificationConfig:entity delegate:self]; 

2、 APNS后 啟動極光服務

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Required // init Push // notice: 2.1.5版本的SDK新增的注冊方法,改成可上報IDFA,如果沒有使用IDFA直接傳nil // 如需繼續使用pushConfig.plist文件聲明appKey等配置內容,請依舊使用[JPUSHService setupWithOption:launchOptions]方式初始化。 [JPUSHService setupWithOption:launchOptions appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:advertisingId]; } 

2、 注冊APNs成功並上報DeviceToken 到極光的后台

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [JPUSHService registerDeviceToken:deviceToken]; } 

2.5 、 實現注冊APNs失敗接口(可選)

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { //Optional NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error); } 

3 、 添加處理APNs通知回調方法
請在AppDelegate.m實現該回調方法並添加回調方法中的代碼
下面的回調方法,其實就是上面注冊極光時的JPUSHRegisterDelegate代理方法

#pragma mark- JPUSHRegisterDelegate // iOS 10 Support // 展示推送之前觸發,可以在此替換推送內容,更改展示效果:內容、聲音、角標。 - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler { // Required NSDictionary * userInfo = notification.request.content.userInfo; if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { [JPUSHService handleRemoteNotification:userInfo]; } completionHandler(UNNotificationPresentationOptionAlert); // 需要執行這個方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以選擇設置 } // iOS 10 Support // 在收到推送后觸發 - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { // Required NSDictionary * userInfo = response.notification.request.content.userInfo; if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { [JPUSHService handleRemoteNotification:userInfo]; } completionHandler(); // 系統要求執行這個方法 } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // Required, iOS 7 Support [JPUSHService handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Required,For systems with less than or equal to iOS6 [JPUSHService handleRemoteNotification:userInfo]; } 

關於極光 代理的兩個方法調用順序
關於極光推送 iOS 兩個方法什么時候走的問題
官方說明

4、如果項目中需要接收自定義信息的功能, 則需要添加監聽自定義消息的方法 (可選)

只有在前端運行的時候才能收到自定義消息的推送。
從jpush服務器獲取用戶推送的自定義消息內容和標題以及附加字段等

獲取iOS的推送內容需要在delegate類中注冊通知並實現回調方法。 在方法didFinishLaunchingWithOptions 加入下面的代碼: 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions { NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil]; } 並且實現通知的回調方法 networkDidReceiveMessage - (void)networkDidReceiveMessage:(NSNotification *)notification { NSDictionary * userInfo = [notification userInfo]; NSString *content = [userInfo valueForKey:@"content"]; NSDictionary *extras = [userInfo valueForKey:@"extras"]; NSString *customizeField1 = [extras valueForKey:@"customizeField1"]; //服務端傳遞的Extras附加字段,key是自己定義的 } 

5、 監聽極光登錄成功的通知,查看是否入庫極光成功, 在這個方法中可以 設置別名; 不過應用的邏輯 是 用戶登錄成功后才可以推送,所以在這里增加了判斷用戶是否登錄的方法。

 (void)networkDidLogin:(NSNotification *)notification { DDLog(@"jpush已登錄,通知詳情為%@",notification.userInfo); //向極光注冊別名 User *user = [UserManager sharedInstace].usr; if( user.isLogin && user.device.tmpPushAliasName ){ user.device.pushAliasName = user.device.tmpPushAliasName; } } 

6、真機調試該項目,如果控制台輸出以下日志則代表您已經集成成功。

2017-05-17 11:24:05.968565+0800 DDRide[22015:4672102] | JIGUANG | I - [JIGUANGRegistration] ----- register result ----- uid: 942xxxx1223 registrationID:13165fxxxx97541104 2017-05-17 11:24:05.970270+0800 DDRide[22015:4671830] [函數名:-[JpushManager networkDidRegister:]]----[行號:74] jpush已注冊 2017-05-17 11:24:06.108945+0800 DDRide[22015:4672119] | JIGUANG | I - [JIGUANGLogin] ----- login result ----- uid:942xx61223 registrationID:13165ffxxxx7541104 2017-05-17 11:24:06.112224+0800 DDRide[22015:4671830] [函數名:-[JpushManager networkDidLogin:]]----[行號:78] jpush已登錄,通知詳情-(null) 2017-05-17 11:24:06.266877+0800 DDRide[22015:4672102] | JIGUANG | I - [JIGUANGDeviceTokenReport] try to upload device token:152ff6a08ec7927xxxxxxxxxxxe603cd642f5f4cab8cae10ab8e 2017-05-17 11:24:06.437331+0800 DDRide[22015:4672102] | JIGUANG | I - [JIGUANGBadgeNumberReport] set badge:0 succeed 2017-05-17 11:24:06.535148+0800 DDRide[22015:4672119] | JIGUANG | I - [JIGUANGDeviceTokenReport] upload device token success 

7、 新增功能 接收本地通知 , 該代理方法已經適配iOS10

- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^) (NSInteger))completionHandler; // if (![notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { // 本地通知為notification // } - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler: (void (^)())completionHandler; // if (![response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { // 本地通知為response.notification // } 

測試結果

  1. 模擬器不能測試極光推送,因為只有真機具備UDID, 才能夠生成DeviceToken
  2. 生產環境證書失效,測試失敗
  3. 登錄成功后,查看 registrationID141fe1dxxxx7a72d ,入庫極光成功,馬上測試別名推送(前台),成功
  4. 后面等待一段時間后,進入后台測試根據registrationID 推送成功, 推送別名149498xxxx0546 成功.
  5. 更換設備后, 沒有登錄的情況下, registrationID變化為13165ffxxxx7541104
  6. 測試 沒有登錄的時候 后台registrationID推送成功 , 別名14949xxxx12183516
  7. 這里有個需要注意的地方是,如果服務器是根據別名推送,且每次登錄會產生新的別名,那么情況就比較麻煩.

對於單點登錄的問題,
環境: 設備A已經登錄, 設備B同賬戶登錄, 更新了別名, 服務器根據同用戶的舊別名發送一個通知, 設備A接收到通知后,退出登錄.
可以這樣處理.服務器保留上一次的別名和最新的別名.
如果自己的服務器保存的是最新的別名, 根據最新的別名推送,則最新登錄的設備是能夠收到消息,而使用舊的別名,新設備不會接受到, 只有上一個登錄的設備會接收.
因為一個別名對於一個注冊ID, 一個注冊ID則對於一個 DeviceToken,而一個DeviceToken則能夠尋找到唯一設備的唯一應用, 這種一一對應的關系,只要某一環出了問題,推送就不可以送達,更不要說設備如果網絡環境差的話,同樣APNS不會推送到設備應用上.

常見問題

1、 iOS 9系統,應用卸載重裝,APNs返回的devicetoken會發生變化,開發者需要獲取設備最新的Registration id。請在kJPFNetworkDidLoginNotification的實現方法里面調用"RegistrationID"這個接口來獲取 RegistrationID。
2、 為什么iOS收不到推送消息?

  • iOS接受消息必要條件是:應用程序的證書要和你上傳到jpush portal上的證書對應,如果你的程序是直接在xcode上運行的,你的應用部署環境必須是開發狀態才能收到APNS消息。
  • 確認 appKey 在 SDK 客戶端與 Portal 上設置是一致,其他環節也按照文檔正確地操作。
  • 檢查 Portal 上上傳的證書,是 APNs (Push) 證書。
  • 再次檢查證書選擇是否正確,參考iOS 證書設置指南89。
  • 推送時選擇的環境與測試設備的打包環境必須一致。測試說明109
  • 嚴肅說明:api推送的時候通過參數 apns_production 來指定推送環境,false為開發環境,true為生產環境。V3 api不帶此參數則默認為生產環境,V3 api封裝的 sdk 默認為開發環境。如果api有傳apns_production則以此值為准。
  • 另外,請確認設備網絡是否正常,如果設備離線,期間推送多條,apns服務器只會離線保留一條

3、 應用產生的設備信息是否變化
自iOS9開始,卸載重裝、長時間關閉推送后又打開等情況 會產生新的token,因此有對應的新的registrationID。(如果用了idfa,在用戶沒有選擇限制廣告跟蹤,並且未點擊『還原廣告標識』時,這個值是不會變的,對應的token也不會改變。)

 溫馨提示:
 * Registration id 需要在執行到kJPFNetworkDidLoginNotification的方法里獲取 * extern NSString * const kJPFNetworkDidReceiveMessageNotification; // 收到自定義消息(非APNS) 其中,kJPFNetworkDidReceiveMessageNotification傳遞的數據可以通過NSNotification中的userInfo方法獲取,包括標題、內容、extras信息等 * 主要是在項目的登錄成功或者自動登錄后,使用用戶的唯一標示進行綁定,或者根據需求添加一些前綴 * 用戶進行退出登錄的方法里添加去除綁定即可,值得注意的是用到即時通訊的話,被擠下線也要去除綁定,已被坑,貼代碼: //沒有值就代表去除 [JPUSHService setTags:[NSSet set]callbackSelector:nil object:self]; [JPUSHService setAlias:@"" callbackSelector:nil object:self]; [JPUSHService setTags:[NSSet set] alias:@"" callbackSelector:nil target:self]; 

參考鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM