之前做過環信和友盟的推送,照着官方文檔集成其實挺簡單的,今天公司需要,特地做了一下極光推送。不用不知道,原來極光推送集成如此簡單,不得不說說了。
當然做推送錢需要做一些准備工作了,就是推送必須的p12推送證書:開發環境(開發時測試需要的推送證書)、生產環境(發布到AppStore時需要的推送證書),因為xcode已經升級到了7.0以上,所以一些真機測試的配置文件證書就不需要自己手動去創建了,只要有Apple ID,真機測試時,就能自動生成,免費測試:
制作證書的過程就不啰嗦了,詳細看官方文檔或者如下推薦:
http://jingyan.baidu.com/article/c1465413975cba0bfcfc4ccf.html
http://docs.jpush.io/client/ios_tutorials/#ios_1
http://docs.jpush.io/guideline/ios_guide/
http://allluckly.cn/投稿/tuogao28?utm_source=tuicool&utm_medium=referral
創建完證書,就是去極光官網注冊賬號,創建應用,截圖如下:

將創建的證書上傳到應用上了,上傳成功后的截圖如下:

證書上傳成功后,生成APP Key,截圖如下:

好了,這下工作做完了,剩下的就是代碼實現了:
第一步:下載SDK,將需要的兩個文件導入項目中:

集成壓縮包內容
包名為JPush-iOS-SDK-{版本號}
- lib文件夾:包含頭文件 JPUSHService.h,靜態庫文件jpush-ios-x.x.x.a ,支持的iOS版本為 5.0 及以上版本。(請注意:模擬器不支持APNs)
- pdf文件:集成指南
- demo文件夾:示例
第二步:導入需要依賴的庫文件:
必要的框架
- CFNetwork.framework
- CoreFoundation.framework
- CoreTelephony.framework
- SystemConfiguration.framework
- CoreGraphics.framework
- Foundation.framework
- UIKit.framework
- Security.framework
- Xcode7需要的是libz.tbd;Xcode7以下版本是libz.dylib
- Adsupport.framework (獲取IDFA需要;如果不使用IDFA,請不要添加)
第三步:創建一個工具類,名稱為KJJPushHelper,封裝注冊時的各種方法
.h
//
// KJJPushHelper.h //
// Created by xiayuanquan on 16/5/5. // Copyright © 2016年 mac. All rights reserved. //
#import <Foundation/Foundation.h>
@interface KJJPushHelper : NSObject // 在應用啟動的時候調用
+ (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId; // 在appdelegate注冊設備處調用
+ (void)registerDeviceToken:(NSData *)deviceToken; // ios7以后,才有completion,否則傳nil
+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion; // 顯示本地通知在最前面
+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification; @end
.m
//
// KJJPushHelper.m // Created by xiayuanquan on 16/5/5. // Copyright © 2016年 mac. All rights reserved. //
#import "KJJPushHelper.h"
#import "JPUSHService.h"
@implementation KJJPushHelper + (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId{ // Required
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
// ios8之后可以自定義category
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { // 可以添加自定義categories
[JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil]; } else { #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
// ios8之前 categories 必須為nil
[JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil]; #endif } #else
// categories 必須為nil
[JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil]; #endif
// Required
[JPUSHService setupWithOption:launchingOption appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:advertisingId]; return; } + (void)registerDeviceToken:(NSData *)deviceToken { [JPUSHService registerDeviceToken:deviceToken]; return; } + (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion { [JPUSHService handleRemoteNotification:userInfo]; if (completion) { completion(UIBackgroundFetchResultNewData); } return; } + (void)showLocalNotificationAtFront:(UILocalNotification *)notification { [JPUSHService showLocalNotificationAtFront:notification identifierKey:nil]; return; } @end
第四步:創建一個APPDelegate的分類,在該類中調用KJJPushHelper中的類方法
// AppDelegate+KJJPushSDK.h //
// Created by xiayuanquan on 16/5/5. // Copyright © 2016年 mac. All rights reserved. //
#import "AppDelegate.h"
@interface AppDelegate (KJJPushSDK) -(void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; @end
// AppDelegate+KJJPushSDK.m //
// Created by xiayuanquan on 16/5/5. // Copyright © 2016年 mac. All rights reserved. //
#import "AppDelegate+KJJPushSDK.h"
#import "KJJPushHelper.h"
#define JPushSDK_AppKey @"31e01f6a2f6dxxxxxxxxxec"
#define isProduction NO
@implementation AppDelegate (KJJPushSDK) -(void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ [KJJPushHelper setupWithOption:launchOptions appKey:JPushSDK_AppKey channel:nil apsForProduction:isProduction advertisingIdentifier:nil]; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // Required - 注冊 DeviceToken
[KJJPushHelper registerDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Required,For systems with less than or equal to iOS6
[KJJPushHelper handleRemoteNotification:userInfo completion:nil]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // IOS 7 Support Required
[KJJPushHelper handleRemoteNotification:userInfo completion:completionHandler]; // 應用正處理前台狀態下,不會收到推送消息,因此在此處需要額外處理一下
if (application.applicationState == UIApplicationStateActive) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"收到推送消息" message:userInfo[@"aps"][@"alert"] delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定",nil]; [alert show]; } } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { //Optional
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error); } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [KJJPushHelper showLocalNotificationAtFront:notification]; return; } - (void)applicationDidBecomeActive:(UIApplication *)application { [application setApplicationIconBadgeNumber:0]; return; } @end
第五步:在AppDelegate中注冊即可
//注冊極光推送
[self JPushApplication:application didFinishLaunchingWithOptions:launchOptions];
好了,大功告成,插上真機運行:打印結果如下

去官網測試一下:

真機收到消息截圖:

集成過程中遇到的問題,困擾了好久,后來找出來了,分享一下:
當時證書一切都沒有問題,但是總是出現這個打印:
錯誤信息JPUSH | W - [JPUSHClientController] Not get deviceToken yet. Maybe: your certificate not configured APNs? or current network is not so good so APNs registration failed? or there is no APNs register code? Please refer to JPush docs.
推送消息時,出現的提示:

我的原因是:
由於項目之前用到了環信SDK,環信得已經注冊了通知,在AppDelegate中注冊通知,didRegisterForRemoteNotificationsWithDeviceToken與didFailToRegisterForRemoteNotificationsWithError方法,均不執行。。。需到環信注冊通知的地方,再次注冊極光通知。方可以獲取到Token執行。
擴展:極光推送中的定向推送
極光推送中,不使用廣播推送,那么怎樣做到定向推送,是開發者和需求一定會出現的問題,極光推送中可以有兩個唯一值:
(1)注冊Jpush成功后生成的registrationID,這個registrationID是標記設備唯一性的,你發現,當你在啟動多次,注冊Jpush時,這個值是不變的;在同一個設備上,更換用戶登錄,這個值仍然不變;最后,你刪除應用程序,再下載時啟動注冊Jpush,這個值還是不變。這就可以定向向某台設備做推送,如果你能給自己的服務器上傳這個值,並且給這個值綁定一些東西,是不是可以做更多事情呢。
(2)alias:只要了解極光推送的都知道這是設置別名的,官方文檔上說明了這個值不是唯一的,但是建議開發者把它作為用戶的唯一標記。我覺得這個作為唯一值是最好的,當你想定向向某個用戶做推送,或者召喚他回歸我們的應用程序,這個值就太好了。你可以將它設置為userId,這個時候推送就能知道向哪個用戶發了。
本人原創,轉載須注明出處,謝謝!
