不同版本極光推送SDK集成各有差異,集成時一定要注意版本號,樓主已將博文更新成最新的SDK JPush v3.0.2. 各位童鞋先閱讀下JPush v3.0.2的升級指南吧!
極光的最近更新
極光資源下載
JPush SDK v3.0.2 升級指南
更新時間
2017-02-13更新信息
修復:DNS解析失敗帶來的崩潰問題,提升穩定性升級提示
建議升級!
注意:支持 Xcode 8.0 以上版本 開啟 bitcode。升級指南
1.注意 3.0.0及以上版本將不再支持處理器為i386的模擬器。
2.添加libresolv.tbd庫(2.2.0及以上版本要求)
3.Xcode7 升級到 Xcode8,替換原先導入的 .dylib 框架為 .tbd (特別留意)
本博文修改歷史
- 2017.03.25 ------------ JPush v3.0.2
- 2016.12.13 ------------ JPush v2.2.0
- 2016.09.28 ----------- JPush v2.1.9
簡介
iOS10下,遠程推送發生了變化,新增的UserNotifications.framework
將本地推送和遠程推送整合在一起。 最近剛剛更新了Xcode8,自動創建證書和配置文件確實方便許多。琰君分享下以開發環境為例(非生產環境)在Xcode8下,快速集成極光推送并兼顧iOS10。
注意:極光的遠程推送是免費的,并同時兼顧iOS,Android,Windows Phone三個平臺,但相應的用戶統計,終端統計等功能是不免費的。如果你需要用戶統計,終端統計這些功能意味著需要付費才能使用。
參考鏈接
開發證書配置
APNs 推送原理及問題
iOS 推送全解析,你不可不知的所有 Tips!
接下來假設你都了解證書相關的,推送的一些概念和極光推送的知識。那么相信你應該知道需要一臺iOS設備和一個蘋果開發者帳號才能去體驗遠程推送。如果你清楚遠程推送的原理,那可以直接從以下第2步開始。
集成步驟
- 遠程推送原理
- Xcode8創建項目,配置自動創建
App ID
/證書
/配置文件
- 創建APNs 推送證書
- 在極光推送后臺創建應用,并上傳APNs 推送證書
- 項目中集成極光推送SDK
- notification payload 和遠程推送類型
- 獲取 APNs推送內容
- 極光推送后臺發送遠程推送測試
1. 遠程推送原理
當iOS設備連網的情況下,iOS設備和蘋果服務器建立了一個長鏈接,即便應用處于掛起和后臺的狀態,蘋果可以給iOS設備中的應用發送通知。
概念
- iOS:iOS設備
- APNs Server:蘋果服務器
- Your App: 自己的應用
- Your Server:自己的服務器
推送流程
- iOS 應用注冊推送通知,iOS設備將設備的
UDID
和應用的Bundle ID
發送到蘋果服務器。 - 蘋果服務器將接收到的
UDID
和Bundle ID
加密生成一個deviceToken
,并返回給對應iOS應用。 - iOS應用將接收到的
deviceToken
發送到自己的服務器,服務器并保存。 - 自己的服務器需配置APNs 推送證書,當需要推送時,去后臺查詢推送目標設備的
deviceToken
,將notification payload
和deviceToken
一起發送給蘋果服務器。notification payload
是一個JSON字典,包含著發給應用程序的數據,并且包含通知的類型(類型決定系統如何通知用戶)。 - 蘋果服務器通過
deviceToken
找到對應設備下的對應應用,推送消息。
說明
- 真機測試并且包含推送功能需要創建對應App ID/證書/配置文件, 這步可以用Xcode8 自動創建,而不需要到蘋果開發者平臺去創建。如果不是Xcode8,則需要去開發者平臺申請,確保App ID包含推送通知服務,并且在Xcode中配置,保證真機測試即可。
- 我們自己的服務器需要配置 APNs 推送證書,同樣的分為開發證書和生產證書。需要到蘋果開發者平臺去申請。
- 如果不借助第三方推送平臺,我們需要完成推送流程中的1,3,4步。借助極光推送,那么我們只需要完成推送流程中的1,3步,但同樣需要我們完成第4步中的申請APNs 推送證書,并且上傳到極光推送平臺。
2. Xcode8配置自動創建App ID/證書/配置文件
- 在Xcode8下,確保已經登錄付費蘋果開發者帳號。請開啟Application Target的Capabilities->Push Notifications選項。
2.勾選自動管理App ID
/證書
/配置文件
3.檢查Xcode自動創建的App ID
/證書
/配置文件
,保證下圖中第4步App ID包含的遠程推送服務。如果沒問題就可以真機運行了。
3. 創建APNs 推送證書
- 登錄開發者網站,并點擊按鈕創建證書
2.選擇開發環境APNs 推送證書
點擊右下角按鈕創建
3.選擇工程的App ID
4.上傳證書請求文件,不知道的童鞋可參照開發證書配置
5.點擊下載證書,并雙擊安裝到鑰匙串.
6.打開鑰匙串,找到對應的APNs 推送證書,并選擇右鍵導出包含私鑰的證書。(確保證書左側為向右的小箭頭,導出的證書才會包含私鑰.)
7.設置證書名字,并選擇證書存放位置。
8.設置證書密碼,可不填。極光推送支持證書設置密碼,但像leanCloud
推送不支持證書設置密碼,各位童鞋可按照實際情況來。最后輸入電腦開密碼,導出證書。
4. 在極光推送后臺創建應用,并上傳APNs 推送證書
1.登錄極光推送平臺,切換到控制臺,并創建應用。接下來在應用信息中上傳開發推送證書。生產推送證書配置類似,不做贅述。
- 核對應用的
Bundle ID
等信息是否正確.
核對Bundle ID 等信息
5. 項目中集成極光推送SDK
極光推送最新版本3.0.2已支持CocoaPods導入。
- 方式一:CocoaPods導入,一句話搞定。
pod 'JPush', '3.0.2'
- 方式二:手動導入SDK和系統依賴庫
jpush-ios-3.0.2.a jcore-ios-1.1.1.a JPUSHService.h
導入系統依賴庫
CFNetwork.framework
CoreFoundation.framework
CoreTelephony.framework
SystemConfiguration.framework
CoreGraphics.framework
Foundation.framework
UIKit.framework
Security.framework
libz.tbd
Adsupport.framework (獲取IDFA需要;如果不使用IDFA,請不要添加)
UserNotifications.framework(Xcode8及以上)
libresolv.tbd (JPush 2.2.0及以上版本需要)
3. AppDelegate.m 配置
導入以下頭文件
import "JPUSHService.h"
// 如果需要使用idfa功能所需要引入的頭文件(可選)
import <AdSupport/AdSupport.h>
ifdef NSFoundationVersionNumber_iOS_9_x_Max
import <UserNotifications/UserNotifications.h>
endif
并且遵守`<JPUSHRegisterDelegate>`協議
@interface AppDelegate ()<JPUSHRegisterDelegate>
@end
注冊遠程推送,初始化極光推送SDK。
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//-------------注冊遠程推送
//notice: 3.0.0及以后版本注冊可以這樣寫,也可以繼續用之前的注冊方式
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
//-------------極光推送SDK初始化
BOOL isProduction = NO;// NO為開發環境,YES為生產環境
//廣告標識符 如果沒有使用IDFA直接傳nil
NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
[JPUSHService setupWithOption:launchOptions appKey:@"極光推送AppKey"
channel:nil
apsForProduction:isProduction
advertisingIdentifier:advertisingId];
return YES;
}
以上是注冊遠程推送極光版本,很簡潔。下面是注冊遠程推送系統版本,可以參考下。
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 10.0)
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:UNAuthorizationOptionCarPlay | UNAuthorizationOptionSound | UNAuthorizationOptionBadge | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@" iOS 10 request notification success");
}else{
NSLog(@" iOS 10 request notification fail");
}
}];
}
else if (version >= 8.0)
{
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:setting];
}else
{ //iOS <= 7.0
UIRemoteNotificationType type = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:type];
}
//注冊通知
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
將蘋果服務器返回的`deviceToken`,上傳到極光推送服務器。
-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
[JPUSHService registerDeviceToken:deviceToken];
}
注冊遠程通知失敗,比如沒有聯網的狀態下。
-(void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
#####6.notification payload 和遠程推送類型
發送遠程推送的服務器發送給APNs的每個通知都包含payload。 payload是一個JSON字典,包含要發送到應用程序的任何自定義數據,并包含有關推送類型的信息(推送類型決定系統如何通知用戶)。
遠程推送分為普通推送,后臺推送,靜默推送三種方式。以下以遠程推送的類型來討論下payload的構造。以下只考慮iOS7之后的操作系統。
- 普通推送
- payload 構造:包含聲音、內容、角標、自定義字段。
{
aps = {
alert = "顯示內容";//alert對應的值也可以是字典,字典中body鍵的值對應顯示內容
badge = 1; // App 角標,可推送 n、+n、-n 來實現角標的固定、增加、減少
sound = default; // 推送聲音,默認系統三全音,如需使用自己的聲音,需要將聲音文件拖拽&拷貝至 Xcode 工程目錄任意位置,并在推送時指定其文件名
};
proNo = "tb_pro_no_id249349874"; // 自定義字段
DesVc = "ProViewController";
}
- 處于未啟動,系統會顯示通知,點擊通知橫幅啟動,在以下方法中獲取通知內容:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- 處于后臺,系統會顯示通知,但不會通知對應應用(即應用的方法不會被調用)。
- 處于前臺,iOS10之后會顯示通知。(iOS10之前會不會展示通知,樓主也記不住了??)在以下方法中獲取通知內容:
- iOS7 ~ iOS9
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void(^(UIBackgroundFetchResult))completionHandler
- iOS10 after (UNUserNotificationCenterDelegate中的代理方法)
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
- 后臺推送
- 必須在 Xcode 工程中 TARGETS – Capabilities – Background Modes 中開啟Remote notifications功能。
- payload構造:必須攜帶 "content-available" = 1,必須攜帶 alert中的顯示信息、badge、sound 中 至少 1 個字段。
{
aps = {
alert = "顯示內容";//alert對應的值也可以是字典,字典中body鍵的值對應顯示內容
badge = 1;
"content-available" = 1; // 必帶字段
sound = default;
};
key1 = value1;
}
- 處于未啟動,同上述普通推送一致。
- 處于后臺或者掛起,系統會顯示通知。通過下述獲取通知內容,你的應用會在后臺啟動(如果應用為掛起狀態,則喚醒它,處于后臺狀態),將有30秒的時間進行處理通知或者下載數據等操作。
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void(^(UIBackgroundFetchResult))completionHandler
- 處于前臺, 系統會顯示通知。可通過以下方法獲取內容:
- iOS7 after
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void(^(UIBackgroundFetchResult))completionHandler
- 注:iOS10 之后除了會調用上面的方法,還會調用此方法 (UNUserNotificationCenterDelegate中的代理方法)
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
- 靜默推送
- 系統不會顯示通知,用戶不會有任何察覺。
- payload構造:必須攜帶 "content-available" = 1。必須不攜帶 alert中的顯示內容、badge、sound。
{
aps = {
alert = "";//alert對應的值也可以為字典,字典中不能包含body鍵值對。
"content-available" = 1; // 必帶字段
};
key1 = value1;
}
- 處于未啟動,獲取不到通知內容
- 處于后臺,iOS7 之后你的應用會在后臺啟動(如果應用為掛起狀態,則喚醒它,處于后臺狀態),將有30秒的時間進行處理通知或者下載數據等操作。可通過下述方法獲取內容:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void(^(UIBackgroundFetchResult))completionHandler
- 處于前臺, iOS7 之后可通過下述方法獲取內容:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void(^(UIBackgroundFetchResult))completionHandler
#####7.獲取 APNs(通知) 推送內容
iOS 設備收到一條推送(APNs),用戶點擊推送通知打開應用時,應用程序根據狀態不同進行處理,需在 AppDelegate 中的以下方法中添加代碼以獲取apn內容。
- 如果 App 狀態為未運行,此函數將被調用,如果launchOptions包含UIApplicationLaunchOptionsRemoteNotificationKey表示用戶點擊apn 通知導致app被啟動運行;如果不含有對應鍵值則表示 App 不是因點擊apn而被啟動,可能為直接點擊icon被啟動或其他。
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
// apn 內容獲取:
NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey]
}
2.基于iOS 6 及以下的系統版本,如果 App狀態為正在前臺或者點擊通知欄的通知消息,那么此函數將被調用,并且可通過AppDelegate的applicationState是否為UIApplicationStateActive判斷程序是否在前臺運行。
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo{
}
3.此方法會在以下幾種情況下調用
- iOS7 ~ iOS9 前臺接收普通推送。
- iOS7之后開啟Background Mode Remote Notification特性,在前臺或者后臺接收到后臺推送和靜默推送。
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {
[JPUSHService handleRemoteNotification:userInfo];
NSLog(@"iOS7及以上系統,收到通知:%@", [self logDic:userInfo]);
completionHandler(UIBackgroundFetchResultNewData);
}
-(NSString *)logDic:(NSDictionary *)dic {
if (![dic count]) {
return nil;
}
NSString *tempStr1 =
[[dic description] stringByReplacingOccurrencesOfString:@"\u"
withString:@"\U"];
NSString *tempStr2 =
[tempStr1 stringByReplacingOccurrencesOfString:@""" withString:@"\""];
NSString *tempStr3 =
[[@""" stringByAppendingString:tempStr2] stringByAppendingString:@"""];
NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
NSString *str =
[NSPropertyListSerialization propertyListFromData:tempData
mutabilityOption:NSPropertyListImmutable
format:NULL
errorDescription:NULL];
return str;
}
4.基于iOS 10及以上的系統版本,
原`[application: didReceiveRemoteNotification:]`將會被系統廢棄,
由新增`UserNotifications.framework`中的以下兩個方法替代。
[UNUserNotificationCenterDelegate willPresentNotification:withCompletionHandler:]
[UNUserNotificationCenterDelegate didReceiveNotificationResponse:withCompletionHandler:]
在極光推送SDK2.1.9版本以后可實現SDK封裝的JPUSHRegisterDelegate協議方法,適配iOS10新增的delegate協議方法。
即以下兩個方法:
ifdef NSFoundationVersionNumber_iOS_9_x_Max
pragma mark- JPUSHRegisterDelegate
//前臺收到推送,可以采取必要的措施處理通知和更新APP的內容。
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary * userInfo = notification.request.content.userInfo;
UNNotificationRequest *request = notification.request; // 收到推送的請求
UNNotificationContent *content = request.content; // 收到推送的消息內容
NSNumber *badge = content.badge; // 推送消息的角標
NSString *body = content.body; // 推送消息體
UNNotificationSound *sound = content.sound; // 推送消息的聲音
NSString *subtitle = content.subtitle; // 推送消息的副標題
NSString *title = content.title; // 推送消息的標題
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
NSLog(@"iOS10 前臺收到遠程通知:%@", [self logDic:userInfo]);
}
// 指定系統如何提醒用戶,有Badge、Sound、Alert三種類型可以設置
// 如果不需提醒可傳UNNotificationPresentationOptionNone
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
}
//當用戶點擊了通知的某個操作,需要進行相應處理,如跳轉到某個界面
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
UNNotificationRequest *request = response.notification.request; // 收到推送的請求
UNNotificationContent *content = request.content; // 收到推送的消息內容
NSNumber *badge = content.badge; // 推送消息的角標
NSString *body = content.body; // 推送消息體
UNNotificationSound *sound = content.sound; // 推送消息的聲音
NSString *subtitle = content.subtitle; // 推送消息的副標題
NSString *title = content.title; // 推送消息的標題
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
NSLog(@"iOS10 收到遠程通知:%@", [self logDic:userInfo]);
}
// 讓系統知道你已處理完通知。
completionHandler();
}
endif
#####8. 極光推送后臺發送遠程推送測試
1.登錄`極光推送`,切換到控制臺,并點擊對應的應用,點擊推送按鈕


2.設置推送內容

選擇推送環境iOS開發環境,目標人群,發送時間。再點擊可選設置設置消息的具體內容。

3.設置消息具體內容。

4.iOS設備接收到遠程推送

以下為打印的通知內容。
{
"_j_msgid" = 3017423712;
aps = {
alert = {
body = "你愛談天,我愛笑~~";
subtitle = "每天堅持1小時,會有大收獲。";
title = "天天";
};
badge = 100;
sound = default;
};
}
5.推送歷史可以在這里看得到,但有延遲,可能遠程推送已接收到,推送歷史數據還沒有更新到最新。

關于Xcode8下集成極光遠程推送的簡單介紹,到這里就結束了。