前言
之前說會單獨整理訊息通知的內容,但是因為工(就)作(是)的(很)事(懶)沒有更新文章,違背了自己的學習的初衷。因為網際網路一定要有危機意識,說不定眼一睜,我們就out丟了飯碗。
“狼,他沒有獅子老虎強壯,也沒有大象那龐大的身軀,但至少:我從來沒在馬戲團看到過他們的身影。”
也許只有狼在一直奔跑,這是我一直喜歡它的原因,要像狼一樣不斷奔跑,才能倖存!
看完樓主裝的一手好X,我來總結一點點你都知道的通知方面的知識點!
背景
iOS10 新特性一出,各個大神就早已研究新特效能給場景智慧化所帶來的好處(唉,可惜我只是一個小白)。我也被安排適配iOS10的推送工作!
Apple 表示這是 iOS 有史以來最大的升級(our biggest release yet),更加智慧開放的 Siri 、強化應用對 3D Touch 支援、 HomeKit 、電話攔截及全新設計的通知等等…
iOS 10 中將之前繁雜的推送通知統一成UserNotifications.framework 來集中管理和使用通知功能,還增加一些實用的功能——撤回單條通知、更新已展示通知、中途修改通知內容、在通知中顯示多媒體資源、自定義UI等功能,功能著實強大!
本文主要是針對iOS 10的訊息通知做介紹,所以很多程式碼沒有對iOS 10之前做新增適配。
基本原理
iOS推送分為Local Notifications(本地推送) 和 Remote Notifications(遠端推送)(原理圖來源於網路,如有侵權請告知,我會新增來源,我怕我賠不起)
Local Notifications(本地推送)
- App本地建立通知,加入到系統的Schedule裡,
- 如果觸發器條件達成時會推送相應的訊息內容
Remote Notifications(遠端推送)
圖中,Provider是指某個iPhone軟體的Push伺服器,這篇文章我將使用我花了12塊大洋(心疼)買的 APNS Pusher 作為我的推送源。
APNS 是Apple Push Notification Service(Apple Push伺服器)的縮寫,是蘋果的伺服器。
上圖可以分為三個階段:
第一階段:APNS Pusher應用程式把要傳送的訊息、目的iPhone的標識打包,發給APNS。
第二階段:APNS在自身的已註冊Push服務的iPhone列表中,查詢有相應標識的iPhone,並把訊息發到iPhone。
第三階段:iPhone把發來的訊息傳遞給相應的應用程式, 並且按照設定彈出Push通知。
從上圖我們可以看到:
- 首先是應用程式註冊訊息推送。
- IOS跟APNS Server要deviceToken。應用程式接受deviceToken。
- 應用程式將deviceToken傳送給PUSH服務端程式。
- 服務端程式向APNS服務傳送訊息。
- APNS服務將訊息傳送給iPhone應用程式。
基本配置和基本方法
如果只是簡單的本地推送,跳過1 2 步驟,直接到3
1、 如果你的App有遠端推送的話,那你需要開發者賬號的,需要新建一個對應你bundle的push 證書。證書這一塊我就不說了,如果針對證書有什麼問題可以給我留言,我會單獨把證書相關的知識點整理起來!當然本人是非常喜歡的分享的(又裝逼),如果你沒有賬號,我可以把我測試用的證書發給你,用於你的測試和學習,私聊我。
2、 Capabilities中開啟Push Notifications 開關
在XCode7中這裡的開關不開啟,推送也是可以正常使用的,但是在XCode8中,這裡的開關必須要開啟,不然會報錯:
1 |
Error Domain=NSCocoaErrorDomain Code=3000 "未找到應用程式的“aps-environment”的授權字串" UserInfo={NSLocalizedDescription=未找到應用程式的“aps-environment”的授權字串} |
開啟後會自動在專案裡生成entitlements檔案。
3、 推送的註冊
第一步: 匯入 #import
且要遵守的協議,在Appdelegate.m中。
這裡需要注意,我們最好寫成這種形式(防止低版本找不到標頭檔案出現問題)
1 2 3 |
#ifdef NSFoundationVersionNumber_iOS_9_x_Max #import #endif |
第二步:我們需要在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
中註冊通知,程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self replyPushNotificationAuthorization:application]; return YES; } #pragma mark - 申請通知許可權 // 申請通知許可權 - (void)replyPushNotificationAuthorization:(UIApplication *)application{ if (IOS10_OR_LATER) { //iOS 10 later UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; //必須寫代理,不然無法監聽通知的接收與點選事件 center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error && granted) { //使用者點選允許 NSLog(@"註冊成功"); }else{ //使用者點選不允許 NSLog(@"註冊失敗"); } }]; // 可以通過 getNotificationSettingsWithCompletionHandler 獲取許可權設定 //之前註冊推送服務,使用者點選了同意還是不同意,以及使用者之後又做了怎樣的更改我們都無從得知,現在 apple 開放了這個 API,我們可以直接獲取到使用者的設定資訊了。注意UNNotificationSettings是隻讀物件哦,不能直接修改! [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { NSLog(@"========%@",settings); }]; }else if (IOS8_OR_LATER){ //iOS 8 - iOS 10系統 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; }else{ //iOS 8.0系統以下 [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; } //註冊遠端訊息通知獲取device token [application registerForRemoteNotifications]; } |
上面需要注意:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
1. 必須寫代理,不然無法監聽通知的接收與點選事件 center.delegate = self; 下面是我在專案裡定義的巨集 #define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) #define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) #define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) #define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 2. 之前註冊推送服務,使用者點選了同意還是不同意,以及使用者之後又做了怎樣的更改我們都無從得知,現在 apple 開放了這個 API,我們可以直接獲取到使用者的設定資訊了。注意UNNotificationSettings是隻讀物件哦,不能直接修改!只能通過以下方式獲取 [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { NSLog(@"========%@",settings); }]; 列印資訊如下: ======== |
4、 遠端推送需要獲取裝置的Device Token的方法是沒有變的,程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#pragma mark - 獲取device Token //獲取DeviceToken成功 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ //解析NSData獲取字串 //我看網上這部分直接使用下面方法轉換為string,你會得到一個nil(別怪我不告訴你哦) //錯誤寫法 //NSString *string = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding]; //正確寫法 NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@""]]; deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"deviceToken===========%@",deviceString); } //獲取DeviceToken失敗 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ NSLog(@"[DeviceToken Error]:%@\n",error.description); } |
5、這一步吊了,這是iOS 10系統更新時,蘋果給了我們2個代理方法來處理通知的接收和點選事件,這兩個方法在的協議中,大家可以檢視下。
1 2 3 4 5 6 7 8 9 10 11 |
@protocol UNUserNotificationCenterDelegate @optional // The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); // 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:. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED; @end |
此外,蘋果把本地通知跟遠端通知合二為一。區分本地通知跟遠端通知的類是UNPushNotificationTrigger.h
類中,UNPushNotificationTrigger
的型別是新增加的,通過它,我們可以得到一些通知的觸發條件 ,解釋如下:
- UNPushNotificationTrigger (遠端通知) 遠端推送的通知型別
- UNTimeIntervalNotificationTrigger (本地通知) 一定時間之後,重複或者不重複推送通知。我們可以設定timeInterval(時間間隔)和repeats(是否重複)。
- UNCalendarNotificationTrigger(本地通知) 一定日期之後,重複或者不重複推送通知 例如,你每天8點推送一個通知,只要dateComponents為8,如果你想每天8點都推送這個通知,只要repeats為YES就可以了。
- UNLocationNotificationTrigger (本地通知)地理位置的一種通知,
當使用者進入或離開一個地理區域來通知。
現在先提出來,後面我會一一程式碼演示出每種用法。還是回到兩個很吊的代理方法吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#pragma mark - iOS10 收到通知(本地和遠端) UNUserNotificationCenterDelegate //App處於前臺接收通知時 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{ //收到推送的請求 UNNotificationRequest *request = notification.request; //收到推送的內容 UNNotificationContent *content = request.content; //收到使用者的基本資訊 NSDictionary *userInfo = content.userInfo; //收到推送訊息的角標 NSNumber *badge = content.badge; //收到推送訊息body NSString *body = content.body; //推送訊息的聲音 UNNotificationSound *sound = content.sound; // 推送訊息的副標題 NSString *subtitle = content.subtitle; // 推送訊息的標題 NSString *title = content.title; if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { //此處省略一萬行需求程式碼。。。。。。 NSLog(@"iOS10 收到遠端通知:%@",userInfo); }else { // 判斷為本地通知 //此處省略一萬行需求程式碼。。。。。。 NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo); } // 需要執行這個方法,選擇是否提醒使用者,有Badge、Sound、Alert三種型別可以設定 completionHandler(UNNotificationPresentationOptionBadge| UNNotificationPresentationOptionSound| UNNotificationPresentationOptionAlert); } //App通知的點選事件 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{ //收到推送的請求 UNNotificationRequest *request = response.notification.request; //收到推送的內容 UNNotificationContent *content = request.content; //收到使用者的基本資訊 NSDictionary *userInfo = content.userInfo; //收到推送訊息的角標 NSNumber *badge = content.badge; //收到推送訊息body NSString *body = content.body; //推送訊息的聲音 UNNotificationSound *sound = content.sound; // 推送訊息的副標題 NSString *subtitle = content.subtitle; // 推送訊息的標題 NSString *title = content.title; if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { NSLog(@"iOS10 收到遠端通知:%@",userInfo); //此處省略一萬行需求程式碼。。。。。。 }else { // 判斷為本地通知 //此處省略一萬行需求程式碼。。。。。。 NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo); } //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. completionHandler(); // 系統要求執行這個方法 } |
需要注意的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
1.下面這個代理方法,只會是app處於前臺狀態 前臺狀態 and 前臺狀態下才會走,後臺模式下是不會走這裡的 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler 2.下面這個代理方法,只會是使用者點選訊息才會觸發,如果使使用者長按(3DTouch)、Action等並不會觸發。 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler 3.點選代理最後需要執行:completionHandler(); // 系統要求執行這個方法 不然會報: 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. 4.不管前臺後臺狀態下。推送訊息的橫幅都可以展示出來!後臺狀態不用說,前臺時需要在前臺代理方法中設定 ,設定如下: // 需要執行這個方法,選擇是否提醒使用者,有Badge、Sound、Alert三種型別可以設定 completionHandler(UNNotificationPresentationOptionBadge| UNNotificationPresentationOptionSound| UNNotificationPresentationOptionAlert); |
6、 iOS 10之前接收通知的相容方法
1 2 3 4 5 6 7 8 9 10 11 12 |
#pragma mark -iOS 10之前收到通知 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"iOS6及以下系統,收到通知:%@", userInfo); //此處省略一萬行需求程式碼。。。。。。 } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSLog(@"iOS7及以上系統,收到通知:%@", userInfo); completionHandler(UIBackgroundFetchResultNewData); //此處省略一萬行需求程式碼。。。。。。 } |
段結:是不是以為就結束了?NO NO NO(你以為離開了幻境,其實才剛剛踏入幻境!)上面的介紹了基本原理、基本配置以及基本方法說明,現在做完這些工作,我們的學習才剛剛開始!現在天時、地利、人和、可以開始下面推送coding的學習和測試了。
在使用者日常生活中會有很多種情形需要通知,比如:新聞提醒、定時吃藥、定期體檢、到達某個地方提醒使用者等等,這些功能在 UserNotifications 中都提供了相應的介面。
我們先學會基本的技能簡單的推送(爬),後面在學習進階定製推送(走),最後看看能不能高階推送(飛不飛起來看個人了,我是飛不起來):
基本Local Notifications(本地推送) 和 Remote Notifications(遠端推送)
一、 基本的本地推送
本地推送生成主要流程就是:
1 2 3 4 |
1. 建立一個觸發器(trigger) 2. 建立推送的內容(UNMutableNotificationContent) 3. 建立推送請求(UNNotificationRequest) 4. 推送請求新增到推送管理中心(UNUserNotificationCenter)中 |
1、新功能trigger可以在特定條件觸發,有三類:UNTimeIntervalNotificationTrigger、UNCalendarNotificationTrigger、UNLocationNotificationTrigger
1.1、 UNTimeIntervalNotificationTrigger:一段時間後觸發(定時推送)
1 2 3 |
//timeInterval:單位為秒(s) repeats:是否迴圈提醒 //50s後提醒 UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:50 repeats:NO]; |
1.2 UNCalendarNotificationTrigger :呼叫
+ (instancetype)triggerWithDateMatchingComponents:(NSDateComponents *)dateComponents repeats:(BOOL)repeats;
進行註冊;時間點資訊用 NSDateComponents.(定期推送)
1 2 3 4 5 6 7 |
//在每週一的14點3分提醒 NSDateComponents *components = [[NSDateComponents alloc] init]; components.weekday = 2; components.hour = 16; components.minute = 3; // components 日期 UNCalendarNotificationTrigger *calendarTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES]; |
1.3、UNLocationNotificationTrigger:呼叫
+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats;
進行註冊,地區資訊使用CLRegion的子類CLCircularRegion,可以配置region屬性 notifyOnEntry和notifyOnExit,是在進入地區、從地區出來或者兩者都要的時候進行通知,這個測試過程專門從公司跑到家時刻關注手機有推送嘛,果然是有的(定點推送)
1 2 3 4 5 6 7 8 |
//首先得匯入#import ,不然會regin建立有問題。 // 建立位置資訊 CLLocationCoordinate2D center1 = CLLocationCoordinate2DMake(39.788857, 116.5559392); CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center1 radius:500 identifier:@"經海五路"]; region.notifyOnEntry = YES; region.notifyOnExit = YES; // region 位置資訊 repeats 是否重複 (CLRegion 可以是地理位置資訊) UNLocationNotificationTrigger *locationTrigger = [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES]; |
2、建立推送的內容(UNMutableNotificationContent)
UNNotificationContent:屬性readOnly
UNMutableNotificationContent:屬性有title、subtitle、body、badge、sound、lauchImageName、userInfo、attachments、categoryIdentifier、threadIdentifier
本地訊息內容 | 內容限制大小 | 展示 |
---|---|---|
title | NSString | 限制在一行,多出部分省略號 |
subtitle | NSString | 限制在一行,多出部分省略號 |
body | NSString | 通知欄出現時,限制在兩行,多出部分省略號;預覽時,全部展示 |
注意點: body中printf風格的轉義字元,比如說要包含%,需要寫成%% 才會顯示,\同樣
1 2 3 4 5 6 7 8 |
// 建立通知內容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此物件為不可變物件。 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"Dely 時間提醒 - title"; content.subtitle = [NSString stringWithFormat:@"Dely 裝逼大會競選時間提醒 - subtitle"]; content.body = @"Dely 裝逼大會總決賽時間到,歡迎你參加總決賽!希望你一統X界 - body"; content.badge = @666; content.sound = [UNNotificationSound defaultSound]; content.userInfo = @{@"key1":@"value1",@"key2":@"value2"}; |
3、建立完整的本地推送請求Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//定時推送 + (void)createLocalizedUserNotification{ // 設定觸發條件 UNNotificationTrigger UNTimeIntervalNotificationTrigger *timeTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0f repeats:NO]; // 建立通知內容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此物件為不可變物件。 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"Dely 時間提醒 - title"; content.subtitle = [NSString stringWithFormat:@"Dely 裝逼大會競選時間提醒 - subtitle"]; content.body = @"Dely 裝逼大會總決賽時間到,歡迎你參加總決賽!希望你一統X界 - body"; content.badge = @666; content.sound = [UNNotificationSound defaultSound]; content.userInfo = @{@"key1":@"value1",@"key2":@"value2"}; // 建立通知標示 NSString *requestIdentifier = @"Dely.X.time"; // 建立通知請求 UNNotificationRequest 將觸發條件和通知內容新增到請求中 UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger]; UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; // 將通知請求 add 到 UNUserNotificationCenter [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (!error) { NSLog(@"推送已新增成功 %@", requestIdentifier); //你自己的需求例如下面: UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"本地通知" message:@"成功新增推送" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; [alert addAction:cancelAction]; [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil]; //此處省略一萬行需求。。。。 } }]; } |
執行結果如下:
二、 基本的遠端推送
如果你想模擬遠端推送,按照我前面介紹的配置基本環境、證書、push開關和基本方法就可以模擬遠端的基本遠端推送。
1、執行工程則會拿到裝置的Device Token,後面會用到。
2、現在我們需要一個推送伺服器給APNS傳送資訊。我前面說了我花了12塊大洋(心疼死我了)買了一個APNS pusher 來模擬遠端推送服務,當然你可以不花錢也可以用到,例如:
NWPusher
3、你需要把你剛剛獲取的device token填到相應位置,同時你要配置好push證書哦。
4、需要新增aps內容了,然後點選send就OK了
1 2 3 4 5 6 7 8 9 10 |
{ "aps" : { "alert" : { "title" : "iOS遠端訊息,我是主標題!-title", "subtitle" : "iOS遠端訊息,我是主標題!-Subtitle", "body" : "Dely,why am i so handsome -body" }, "badge" : "2" } } |
5、稍縱即逝你就收到了遠端訊息了
6、Notification Management
對推送進行查、改、刪。都需要一個必需的引數requestIdentifier
1、更新通知
Local Notification需要通過更新request.相同的requestIdentifier,重新新增到推送center就可以了,說白了就是重新建立local Notification request(只要保證requestIdentifier就ok了),應用場景如圖
Remote Notification 更新需要通過新的欄位apps-collapse-id
來作為唯一標示,我前面用的APNS pusher暫不支援這個欄位,不過github上有很多這樣的工具:
https://github.com/KnuffApp/Knuff
這樣remote 也可以更新推送訊息
2、推送訊息的查詢和刪除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Notification requests that are waiting for their trigger to fire //獲取未送達的所有訊息列表 - (void)getPendingNotificationRequestsWithCompletionHandler:(void(^)(NSArray *requests))completionHandler; //刪除所有未送達的特定id的訊息 - (void)removePendingNotificationRequestsWithIdentifiers:(NSArray *)identifiers; //刪除所有未送達的訊息 - (void)removeAllPendingNotificationRequests; // Notifications that have been delivered and remain in Notification Center. Notifiations triggered by location cannot be retrieved, but can be removed. //獲取已送達的所有訊息列表 - (void)getDeliveredNotificationsWithCompletionHandler:(void(^)(NSArray *notifications))completionHandler __TVOS_PROHIBITED; //刪除所有已送達的特定id的訊息 - (void)removeDeliveredNotificationsWithIdentifiers:(NSArray *)identifiers __TVOS_PROHIBITED; //刪除所有已送達的訊息 - (void)removeAllDeliveredNotifications __TVOS_PROHIBITED; |
測試如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
+ (void)notificationAction{ NSString *requestIdentifier = @"Dely.X.time"; UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; //刪除裝置已收到的所有訊息推送 // [center removeAllDeliveredNotifications]; //刪除裝置已收到特定id的所有訊息推送 // [center removeDeliveredNotificationsWithIdentifiers:@[requestIdentifier]]; //獲取裝置已收到的訊息推送 [center getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { }]; } |
段結: 收到通知時你需要在appdelegate裡面的代理方法裡處理你的需求邏輯,這個需要你自己寫了。到目前為止你掌握了基本的本地推送和基本的遠端推送!
不知不覺寫了這麼多字(全是TM廢話)、本來繼續打算寫進階的本地和遠端推送(Media Attachments、Notification Actions、自定義推送介面等),留著下一篇部落格繼續分享吧,欲知後事如何,且聽下會裝X!
如果你喜歡可以點個喜歡^_^(竟有如此厚顏無恥之人)
下集預告:
參考資料:
https://developer.apple.com/reference/usernotifications
http://www.jianshu.com/p/b74e52e866fc
http://www.jianshu.com/p/b74e52e866fc
http://blog.csdn.net/he317165264/article/details/52574934
http://qoofan.com/read/PnEaMEZonD.html
http://www.qingpingshan.com/rjbc/ios/140921.html