轉自:https://www.jianshu.com/p/1d37efd7d65c
now,我們從建立好極光應用開始,獲得appkey之後,開啟xcode,進入項目,如圖,可以看到有個開關,push notifications
通知開關
開啟開關之後,會產生一個 項目名.entitlements的檔案
entitlements.png
but在這之前,很多人沒有push notificaitons開關,don't worry,進入極光首頁,你會發現,需要匯入各種依賴庫 依賴庫.png
我們在xcode下的Build Phases逐個添加依賴庫,如圖 Build Phases
匯入依賴庫之後,在這裡最關鍵的依賴庫是UserNotificationcations.framework(xcode8及以上),關閉程式,重新啟動,開關就會出現,然後開啟開關,如圖 Push Notifications 在開關下面,steps有兩個項目,第一個如果爆紅,說明沒有匯入項目所需的認證及設定檔(即在apple developer 產生的認證及設定檔) ,匯入即可;如果第二個爆紅,可能是因為你不小心刪除了 項目名.entitlements 檔案,解決方案是,關閉push Notifications開關之後再開啟即可產生,如果不行的話,關閉程式,在關閉開啟開關即可,如果 如果再不行,去你的廢紙簍裡面找被你刪除的 項目名.entitlements 檔案,重新拖到項目中重啟項目即可
Build Settings
如果你的工程需要支援小於7.0的iOS系統,請到Build Settings 關閉 bitCode 選項,否則將無法正常編譯通過。
設定 Search Paths 下的 User Header Search Paths 和 Library Search Paths,比如SDK檔案夾(預設為lib)與工程檔案在同一級目錄下,則都設定為"$(SRCROOT)/{靜態庫所在檔案夾名稱}"即可 。《來自極光文檔》
2.允許Xcode7支援Http傳輸方法
如果您使用的是2.1.9及以上的版本則不需要配置此步驟
如果用的是Xcode7或更新版本,需要在App項目的plist手動設定下key和值以支援http傳輸:
選擇1:根據網域名稱配置
在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型為字典類型。
然後給它添加一個NSExceptionDomains,類型為字典類型;
把需要的支援的域添加給NSExceptionDomains。其中jpush.cn作為Key,類型為字典類型。
每個域下面需要設定2個屬性:NSIncludesSubdomains、NSExceptionAllowsInsecureHTTPLoads。 兩個屬性均為Boolean類型,值分別為YES、YES。《來自極光文檔》 。如圖 Snip20161024_10.png 配置完以上之後,進入項目的appdelegate裡面,首先匯入標頭檔和遵循代理
#import "AppDelegate.h"#import "JPUSHService.h"#ifdef NSFoundationVersionNumber_iOS_9_x_Max#import <UserNotifications/UserNotifications.h>#endif@interface AppDelegate ()<JPUSHRegisterDelegate>
在系統方法裡面申請通知許可權,這裡最高只適用到xcode8.1(iOS10.1.2),以後如果出現iOS11在做更新改變
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init]; entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound; [JPUSHService registerForRemoteNotificationConfig:entity delegate:self]; } else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { //可以添加自訂categories [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil]; } else { //categories 必須為nil [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil]; }[JPUSHService setupWithOption:launchOptions appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:nil]; // 這裡是沒有advertisingIdentifier的情況,有的話,大家在自行添加 //註冊遠端訊息通知擷取device token [application registerForRemoteNotifications];}
注意:appkey一定不要忘了從極光複製過來 擷取deviceToken
// 擷取deviceToken- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ [JPUSHService registerDeviceToken:deviceToken];}
// ios 10 support 處於前台時接收到通知
// ios 10 support 處於前台時接收到通知- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler{ NSDictionary * userInfo = notification.request.content.userInfo; if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { [JPUSHService handleRemoteNotification:userInfo];// 添加各種需求。。。。。 } completionHandler(UNNotificationPresentationOptionAlert); // 處於前台時,添加需求,一般是彈出alert跟使用者進行互動,這時候completionHandler(UNNotificationPresentationOptionAlert)這句話就可以注釋掉了,這句話是系統的alert,顯示在app的頂部,}
*/ 如果處於前台時需要自訂彈框或者彈出alert,可以看一下http://www.jianshu.com/p/d2a42072fad9 這篇文章
// iOS 10 Support 點擊處理事件
// 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]; //推送開啟 if (userInfo) { // 取得 APNs 標準資訊內容// NSDictionary *aps = [userInfo valueForKey:@"aps"];// NSString *content = [aps valueForKey:@"alert"]; //推送顯示的內容// NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數量// NSString *sound = [aps valueForKey:@"sound"]; //播放的聲音 // 添加各種需求。。。。。 [JPUSHService handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData); } completionHandler(); // 系統要求執行這個方法}
// iOS7 及以上接收到通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // Required, iOS 7 Support [JPUSHService handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData);}
這裡在iOS7及以上系統的方法中,如果需要在前台和後台做不同的處理的時候,需要判斷一下app 的狀態,判斷方式如下
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // 處於前台時 ,添加各種需求代碼。。。。 }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { // app 處於後台 ,添加各種需求 }
那麼問題來了,前台後台收到推送的方法都有了,還有一種情況。。。。。程式完全退出的時候,這種情況下,點擊通知會走下面這個方法(即註冊通知時的方法,程式的入口)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{}
在這個方法裡,我們需要判斷一下程式是否處於完全退出狀態,判斷方法如下
NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey]; if (remoteNotification) { // 程式完全退出時,點擊通知,添加需求。。。 }
# 需要注意的地方:有可能有些小夥伴在整合過程中用ios10的手機測試的時候,在推播通知的時候ios10和ios7的兩個代理方法都走了,具體原因具體對待,如果實在找不到問題所在,這裡提供兩個方法,one:在ios10的兩個代理方法的首尾加入以下語句#ifdef NSFoundationVersionNumber_iOS_9_x_Max #endif // ios10中加入這兩句話在ios7的代理方法首尾加入以下語句#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1 #endif // ios7中加入這兩句話第二種方法是直接在ios7的代理方法中加入判斷:if ([[UIDevice currentDevice].systemVersion floatValue] < 10.0)
// 基於iOS 6 及以下的系統版本 接收到通知
// 基於iOS 6 及以下的系統版本,如果 App狀態為正在前台或者點擊通知欄的通知訊息,那麼此函數將被調用,並且可通過AppDelegate的applicationState是否為UIApplicationStateActive判斷程式是否在前台運行。此種情況在此函數中處理:- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Required,For systems with less than or equal to iOS6 // iOS 10 以下 Required [JPUSHService handleRemoteNotification:userInfo];}
//最後清除角標
- (void)applicationDidEnterBackground:(UIApplication *)application { [[UIApplication alloc] setApplicationIconBadgeNumber:0];}// 點擊之後badge清零- (void)applicationWillEnterForeground:(UIApplication *)application { [application setApplicationIconBadgeNumber:0]; [[UNUserNotificationCenter alloc] removeAllPendingNotificationRequests];}
其他功能:
1 . 後台傳入不同的值,點擊通知進入不同的介面,可以在極光的官網發送通知介面,展開可選設定,使用附加欄位,這裡我加了一個索引值對key和值可以自行設定,然後在工程中需要進行判斷, 設定附加欄位
代碼如下:大家可以在點擊通知會走的方法中調用此方法
// 傳入欄位,根據欄位改變需求- (void)ExtrasOfNotificationWithUserInfo:(NSDictionary *)userInfo{ if (userInfo) { // 取得 APNs 標準資訊內容// NSDictionary *aps = [userInfo valueForKey:@"aps"];// NSString *content = [aps valueForKey:@"alert"]; //推送顯示的內容// NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數量// NSString *sound = [aps valueForKey:@"sound"]; //播放的聲音 // 取得Extras欄位內容 NSString *customizeField1 = [userInfo valueForKey:@"key"]; //服務端中Extras欄位,key是自己定義的,需要與極光的附加欄位一致 // 若傳入欄位的值為1,進入相應的頁面 if ([customizeField1 integerValue] == 1){ //是推送開啟 UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; MainTabbarVC *rootTabBarC = [sb instantiateViewControllerWithIdentifier:@"MainTabbarVC"]; [UIApplication sharedApplication].delegate.window.rootViewController = rootTabBarC;// 下面的方法是自己封裝的 [rootTabBarC enterToElectronicInvoice]; } } }
注意:這裡的跳轉方法可能不適用所有項目,大家可以看一下下面的連結,或許能夠找到適合你工程的跳轉方法
2 . 指定使用者發送遠程通知,這裡指定使用者不能只根據DeviceToken來進行發送,在極光的官網也沒有可以使用DeviceToken發送的選項,如下圖 極光發送訊息針對的人群
這裡的Registration ID 並不是DeviceToken,話不多說,下面我們介紹一種使用別名Alias的方法,我們知道指定使用者發送,無非是已經註冊了本公司帳號的人群,你想給不同的人推不同的訊息,那麼我們指定使用者的時候,實際上是根據使用者在我們公司註冊的帳號進行發送特定訊息,例如使用者的賬單狀態等等,所以我們可以在使用者登陸帳號之後,給使用者指派一個id用做唯一標示,綁定極光的別名或者tag,當然這裡綁定別名還是tag可以和後台商量一下,用什麼其實都是可以的,代碼如下
[JPUSHService setTags:nil alias:USER_INFO.userID fetchCompletionHandle:^(int iResCode, NSSet *iTags, NSString *iAlias) { NSLog(@"設定結果:%i 使用者別名:%@",iResCode,USER_INFO.userID); }];// 這是極光提供的方法,USER_INFO.userID是使用者的id,你可以根據帳號或者其他來設定,只要保證唯一便可// 不要忘了在登出之後將別名置空[JPUSHService setTags:nil alias:@"" fetchCompletionHandle:^(int iResCode, NSSet *iTags, NSString *iAlias) { NSLog(@"設定結果:%i 使用者別名:%@",iResCode,USER_INFO.userID); }];
綁定完別名之後,指定使用者發送訊息的任務就可以交給後台了。如果你想自己測試一下,那就列印一下USER_INFO.userID ,然後自己用極光給自己推送,如圖 根據自己的Alias給自己推送訊息
至此,ios極光推送的整合就簡單說到這裡,未完。。。待續。。。覺得好的,就點個贊,有問題的可以私信我,或者加我qq:1162719523,同不同意那就不知道了
ios 收到遠程通知,彈出提示框,點擊確定跳轉到訊息介面:http://www.jianshu.com/p/d2a42072fad9
以下來自:http://blog.csdn.net/qq_26300747/article/details/78454758
關於推送認證的申請不再贅述。
下載極光推送的包之後,直接拖進項目中即可使用。
在appdelegate中插入如下代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [application setApplicationIconBadgeNumber:0]; [application cancelAllLocalNotifications]; 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]; [JPUSHService setupWithOption:launchOptions appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:nil]; return YES;}- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { /// Required - 註冊 DeviceToken [[NSUserDefaults standardUserDefaults] setObject:@{@"deviceType":@"iOS", @"deviceToken":deviceToken} forKey:@"devieceInfo"]; [JPUSHService registerDeviceToken:deviceToken];}- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { //Optional NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);}-(void)didReceiveJPushNotification:(NSDictionary *)notiDict{ //在這裡統一處理接收通知的處理,notiDict為接收到的所有資料}//// iOS 10 Support- (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]); [self didReceiveJPushNotification:userInfo]; } else { // 判斷為本地通知 NSLog(@"iOS10 前台收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo); [self didReceiveJPushNotification:userInfo]; } completionHandler(UNNotificationPresentationOptionSound); // 需要執行這個方法,選擇是否提醒使用者,有Badge、Sound、Alert三種類型可以設定}////// iOS 10 Support- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{ NSDictionary * userInfo = response.notification.request.content.userInfo; UNNotificationRequest *request = response.notification.request; // 收到推送的請求 UNNotificationContent *content = request.content; // 收到推送的訊息內容 NSNumber *badge = content