前言
之前說會(huì)單獨(dú)整理消息通知的內(nèi)容,但是因?yàn)楣?就)作(是)的(很)事(懶)沒有更新文章莺葫,違背了自己的學(xué)習(xí)的初衷。因?yàn)榛ヂ?lián)網(wǎng)一定要有危機(jī)意識(shí)枪眉,說不定眼一睜捺檬,我們就out丟了飯碗。
“狼贸铜,他沒有獅子老虎強(qiáng)壯欺冀,也沒有大象那龐大的身軀,但至少:我從來沒在馬戲團(tuán)看到過他們的身影萨脑∫”
也許只有狼在一直奔跑,這是我一直喜歡它的原因渤早,要像狼一樣不斷奔跑职车,才能幸存!
看完樓主裝的一手好X鹊杖,我來總結(jié)一點(diǎn)點(diǎn)你都知道的通知方面的知識(shí)點(diǎn)悴灵!
背景
iOS10 新特性一出骂蓖,各個(gè)大神就早已研究新特性能給場景智能化所帶來的好處(唉积瞒,可惜我只是一個(gè)小白)。我也被安排適配iOS10的推送工作登下!
Apple 表示這是 iOS 有史以來最大的升級(jí)(our biggest release yet)茫孔,更加智能開放的 Siri 叮喳、強(qiáng)化應(yīng)用對(duì) 3D Touch 支持、 HomeKit 缰贝、電話攔截及全新設(shè)計(jì)的通知等等…
iOS 10 中將之前繁雜的推送通知統(tǒng)一成UserNotifications.framework 來集中管理和使用通知功能馍悟,還增加一些實(shí)用的功能——撤回單條通知、更新已展示通知剩晴、中途修改通知內(nèi)容锣咒、在通知中顯示多媒體資源、自定義UI等功能赞弥,功能著實(shí)強(qiáng)大毅整!
本文主要是針對(duì)iOS 10的消息通知做介紹,所以很多代碼沒有對(duì)iOS 10之前做添加適配绽左。
基本原理
iOS推送分為Local Notifications(本地推送) 和 Remote Notifications(遠(yuǎn)程推送)(原理圖來源于網(wǎng)絡(luò)悼嫉,如有侵權(quán)請(qǐng)告知,我會(huì)添加來源妇菱,我怕我賠不起)
Local Notifications(本地推送)
- App本地創(chuàng)建通知承粤,加入到系統(tǒng)的Schedule里暴区,
- 如果觸發(fā)器條件達(dá)成時(shí)會(huì)推送相應(yīng)的消息內(nèi)容
Remote Notifications(遠(yuǎn)程推送)
圖中闯团,Provider是指某個(gè)iPhone軟件的Push服務(wù)器,這篇文章我將使用我花了12塊大洋(心疼)買的 APNS Pusher 作為我的推送源仙粱。
APNS 是Apple Push Notification Service(Apple Push服務(wù)器)的縮寫房交,是蘋果的服務(wù)器。
上圖可以分為三個(gè)階段:
第一階段:APNS Pusher應(yīng)用程序把要發(fā)送的消息伐割、目的iPhone的標(biāo)識(shí)打包候味,發(fā)給APNS。
第二階段:APNS在自身的已注冊(cè)Push服務(wù)的iPhone列表中隔心,查找有相應(yīng)標(biāo)識(shí)的iPhone白群,并把消息發(fā)到iPhone。
第三階段:iPhone把發(fā)來的消息傳遞給相應(yīng)的應(yīng)用程序硬霍, 并且按照設(shè)定彈出Push通知帜慢。
從上圖我們可以看到:
首先是應(yīng)用程序注冊(cè)消息推送。
IOS跟APNS Server要deviceToken唯卖。應(yīng)用程序接受deviceToken粱玲。
應(yīng)用程序?qū)eviceToken發(fā)送給PUSH服務(wù)端程序。
服務(wù)端程序向APNS服務(wù)發(fā)送消息拜轨。
APNS服務(wù)將消息發(fā)送給iPhone應(yīng)用程序抽减。
基本配置和基本方法
如果只是簡單的本地推送,跳過1 2 步驟,直接到3
1橄碾、 如果你的App有遠(yuǎn)端推送的話卵沉,那你需要開發(fā)者賬號(hào)的颠锉,需要新建一個(gè)對(duì)應(yīng)你bundle的push 證書。證書這一塊我就不說了偎箫,如果針對(duì)證書有什么問題可以給我留言木柬,我會(huì)單獨(dú)把證書相關(guān)的知識(shí)點(diǎn)整理起來!如果你沒有賬號(hào)淹办,可以到某寶買個(gè)眉枕,很便宜。
2怜森、 Capabilities中打開Push Notifications 開關(guān)
在XCode7中這里的開關(guān)不打開速挑,推送也是可以正常使用的,但是在XCode8中副硅,這里的開關(guān)必須要打開姥宝,不然會(huì)報(bào)錯(cuò):
Error Domain=NSCocoaErrorDomain Code=3000 "未找到應(yīng)用程序的“aps-environment”的授權(quán)字符串" UserInfo={NSLocalizedDescription=未找到應(yīng)用程序的“aps-environment”的授權(quán)字符串}
打開后會(huì)自動(dòng)在項(xiàng)目里生成entitlements文件。
3恐疲、 推送的注冊(cè)
第一步: 導(dǎo)入 #import <UserNotifications/UserNotifications.h>
且要遵守<UNUserNotificationCenterDelegate>
的協(xié)議腊满,在Appdelegate.m中。
這里需要注意培己,我們最好寫成這種形式(防止低版本找不到頭文件出現(xiàn)問題)
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
第二步:我們需要在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
中注冊(cè)通知碳蛋,代碼如下
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self replyPushNotificationAuthorization:application];
return YES;
}
#pragma mark - 申請(qǐng)通知權(quán)限
// 申請(qǐng)通知權(quán)限
- (void)replyPushNotificationAuthorization:(UIApplication *)application{
if (IOS10_OR_LATER) {
//iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//必須寫代理,不然無法監(jiān)聽通知的接收與點(diǎn)擊事件
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
//用戶點(diǎn)擊允許
NSLog(@"注冊(cè)成功");
}else{
//用戶點(diǎn)擊不允許
NSLog(@"注冊(cè)失敗");
}
}];
// 可以通過 getNotificationSettingsWithCompletionHandler 獲取權(quán)限設(shè)置
//之前注冊(cè)推送服務(wù)省咨,用戶點(diǎn)擊了同意還是不同意肃弟,以及用戶之后又做了怎樣的更改我們都無從得知,現(xiàn)在 apple 開放了這個(gè) API零蓉,我們可以直接獲取到用戶的設(shè)定信息了笤受。注意UNNotificationSettings是只讀對(duì)象哦,不能直接修改敌蜂!
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"========%@",settings);
}];
}else if (IOS8_OR_LATER){
//iOS 8 - iOS 10系統(tǒng)
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}else{
//iOS 8.0系統(tǒng)以下
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
}
//注冊(cè)遠(yuǎn)端消息通知獲取device token
[application registerForRemoteNotifications];
}
上面需要注意:
1. 必須寫代理箩兽,不然無法監(jiān)聽通知的接收與點(diǎn)擊事件
center.delegate = self;
下面是我在項(xiàng)目里定義的宏
#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. 之前注冊(cè)推送服務(wù),用戶點(diǎn)擊了同意還是不同意章喉,以及用戶之后又做了怎樣的更改我們都無從得知汗贫,現(xiàn)在 apple 開放了這個(gè) API,我們可以直接獲取到用戶的設(shè)定信息了囊陡。注意UNNotificationSettings是只讀對(duì)象哦芳绩,不能直接修改!只能通過以下方式獲取
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"========%@",settings);
}];
打印信息如下:
========<UNNotificationSettings: 0x1740887f0; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, alertSetting: NotSupported, carPlaySetting: Enabled, alertStyle: Banner>
4撞反、 遠(yuǎn)端推送需要獲取設(shè)備的Device Token的方法是沒有變的,代碼如下
#pragma mark - 獲取device Token
//獲取DeviceToken成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
//解析NSData獲取字符串
//我看網(wǎng)上這部分直接使用下面方法轉(zhuǎn)換為string妥色,你會(huì)得到一個(gè)nil(別怪我不告訴你哦)
//錯(cuò)誤寫法
//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系統(tǒng)更新時(shí)嘹害,蘋果給了我們2個(gè)代理方法來處理通知的接收和點(diǎn)擊事件撮竿,這兩個(gè)方法在<UNUserNotificationCenterDelegate>
的協(xié)議中,大家可以查看下笔呀。
@protocol UNUserNotificationCenterDelegate <NSObject>
@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
此外幢踏,蘋果把本地通知跟遠(yuǎn)程通知合二為一。區(qū)分本地通知跟遠(yuǎn)程通知的類是UNPushNotificationTrigger.h
類中许师,UNPushNotificationTrigger
的類型是新增加的房蝉,通過它,我們可以得到一些通知的觸發(fā)條件 ,解釋如下:
- UNPushNotificationTrigger (遠(yuǎn)程通知) 遠(yuǎn)程推送的通知類型
- UNTimeIntervalNotificationTrigger (本地通知) 一定時(shí)間之后,重復(fù)或者不重復(fù)推送通知已艰。我們可以設(shè)置timeInterval(時(shí)間間隔)和repeats(是否重復(fù))。
- UNCalendarNotificationTrigger(本地通知) 一定日期之后檀蹋,重復(fù)或者不重復(fù)推送通知 例如,你每天8點(diǎn)推送一個(gè)通知云芦,只要dateComponents為8俯逾,如果你想每天8點(diǎn)都推送這個(gè)通知,只要repeats為YES就可以了舅逸。
- UNLocationNotificationTrigger (本地通知)地理位置的一種通知桌肴,
當(dāng)用戶進(jìn)入或離開一個(gè)地理區(qū)域來通知。
現(xiàn)在先提出來堡赔,后面我會(huì)一一代碼演示出每種用法识脆。還是回到兩個(gè)很吊的代理方法吧
#pragma mark - iOS10 收到通知(本地和遠(yuǎn)端) UNUserNotificationCenterDelegate
//App處于前臺(tái)接收通知時(shí)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
//收到推送的請(qǐng)求
UNNotificationRequest *request = notification.request;
//收到推送的內(nèi)容
UNNotificationContent *content = request.content;
//收到用戶的基本信息
NSDictionary *userInfo = content.userInfo;
//收到推送消息的角標(biāo)
NSNumber *badge = content.badge;
//收到推送消息body
NSString *body = content.body;
//推送消息的聲音
UNNotificationSound *sound = content.sound;
// 推送消息的副標(biāo)題
NSString *subtitle = content.subtitle;
// 推送消息的標(biāo)題
NSString *title = content.title;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//此處省略一萬行需求代碼设联。善已。。离例。换团。。
NSLog(@"iOS10 收到遠(yuǎn)程通知:%@",userInfo);
}else {
// 判斷為本地通知
//此處省略一萬行需求代碼宫蛆。艘包。。耀盗。想虎。。
NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@叛拷,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@舌厨,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
}
// 需要執(zhí)行這個(gè)方法忿薇,選擇是否提醒用戶裙椭,有Badge躏哩、Sound、Alert三種類型可以設(shè)置
completionHandler(UNNotificationPresentationOptionBadge|
UNNotificationPresentationOptionSound|
UNNotificationPresentationOptionAlert);
}
//App通知的點(diǎn)擊事件
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
//收到推送的請(qǐng)求
UNNotificationRequest *request = response.notification.request;
//收到推送的內(nèi)容
UNNotificationContent *content = request.content;
//收到用戶的基本信息
NSDictionary *userInfo = content.userInfo;
//收到推送消息的角標(biāo)
NSNumber *badge = content.badge;
//收到推送消息body
NSString *body = content.body;
//推送消息的聲音
UNNotificationSound *sound = content.sound;
// 推送消息的副標(biāo)題
NSString *subtitle = content.subtitle;
// 推送消息的標(biāo)題
NSString *title = content.title;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"iOS10 收到遠(yuǎn)程通知:%@",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(); // 系統(tǒng)要求執(zhí)行這個(gè)方法
}
需要注意的:
1.下面這個(gè)代理方法提完,只會(huì)是app處于前臺(tái)狀態(tài) 前臺(tái)狀態(tài) and 前臺(tái)狀態(tài)下才會(huì)走形纺,后臺(tái)模式下是不會(huì)走這里的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
2.下面這個(gè)代理方法,只會(huì)是用戶點(diǎn)擊消息才會(huì)觸發(fā)徒欣,如果使用戶長按(3DTouch)逐样、彈出Action頁面等并不會(huì)觸發(fā)。點(diǎn)擊Action的時(shí)候會(huì)觸發(fā)打肝!
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
3.點(diǎn)擊代理最后需要執(zhí)行:completionHandler(); // 系統(tǒng)要求執(zhí)行這個(gè)方法
不然會(huì)報(bào):
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.不管前臺(tái)后臺(tái)狀態(tài)下脂新。推送消息的橫幅都可以展示出來!后臺(tái)狀態(tài)不用說粗梭,前臺(tái)時(shí)需要在前臺(tái)代理方法中設(shè)置 争便,設(shè)置如下:
// 需要執(zhí)行這個(gè)方法,選擇是否提醒用戶断医,有Badge滞乙、Sound、Alert三種類型可以設(shè)置
completionHandler(UNNotificationPresentationOptionBadge|
UNNotificationPresentationOptionSound|
UNNotificationPresentationOptionAlert);
6鉴嗤、 iOS 10之前接收通知的兼容方法
#pragma mark -iOS 10之前收到通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"iOS6及以下系統(tǒng)斩启,收到通知:%@", userInfo);
//此處省略一萬行需求代碼。醉锅。兔簇。。。男韧。
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"iOS7及以上系統(tǒng)朴摊,收到通知:%@", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
//此處省略一萬行需求代碼。此虑。甚纲。。朦前。介杆。
}
段結(jié):是不是以為就結(jié)束了?NO NO NO(你以為離開了幻境韭寸,其實(shí)才剛剛踏入幻境4荷凇)上面的介紹了基本原理、基本配置以及基本方法說明恩伺,現(xiàn)在做完這些工作赴背,我們的學(xué)習(xí)才剛剛開始!現(xiàn)在天時(shí)晶渠、地利凰荚、人和、可以開始下面推送coding的學(xué)習(xí)和測試了褒脯。
在用戶日常生活中會(huì)有很多種情形需要通知便瑟,比如:新聞提醒、定時(shí)吃藥番川、定期體檢到涂、到達(dá)某個(gè)地方提醒用戶等等,這些功能在 UserNotifications 中都提供了相應(yīng)的接口颁督。
我們先學(xué)會(huì)基本的技能簡單的推送(爬)践啄,后面在學(xué)習(xí)進(jìn)階定制推送(走),最后看看能不能高級(jí)推送(飛不飛起來看個(gè)人了适篙,我是飛不起來):
基本Local Notifications(本地推送) 和 Remote Notifications(遠(yuǎn)程推送)
一往核、 基本的本地推送
本地推送生成主要流程就是:
1. 創(chuàng)建一個(gè)觸發(fā)器(trigger)
2. 創(chuàng)建推送的內(nèi)容(UNMutableNotificationContent)
3. 創(chuàng)建推送請(qǐng)求(UNNotificationRequest)
4. 推送請(qǐng)求添加到推送管理中心(UNUserNotificationCenter)中
1箫爷、新功能trigger可以在特定條件觸發(fā)嚷节,有三類:UNTimeIntervalNotificationTrigger、UNCalendarNotificationTrigger虎锚、UNLocationNotificationTrigger
1.1硫痰、 UNTimeIntervalNotificationTrigger:一段時(shí)間后觸發(fā)(定時(shí)推送)
//timeInterval:單位為秒(s) repeats:是否循環(huán)提醒
//50s后提醒
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:50 repeats:NO];
1.2 UNCalendarNotificationTrigger :調(diào)用
+ (instancetype)triggerWithDateMatchingComponents:(NSDateComponents *)dateComponents repeats:(BOOL)repeats;
進(jìn)行注冊(cè);時(shí)間點(diǎn)信息用 NSDateComponents.(定期推送)
//在每周一的14點(diǎn)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:調(diào)用
+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats;
進(jìn)行注冊(cè)效斑,地區(qū)信息使用CLRegion的子類CLCircularRegion,可以配置region屬性 notifyOnEntry和notifyOnExit柱徙,是在進(jìn)入地區(qū)缓屠、從地區(qū)出來或者兩者都要的時(shí)候進(jìn)行通知奇昙,這個(gè)測試過程專門從公司跑到家時(shí)刻關(guān)注手機(jī)有推送嘛,果然是有的(定點(diǎn)推送)
//首先得導(dǎo)入#import <CoreLocation/CoreLocation.h>敌完,不然會(huì)regin創(chuàng)建有問題储耐。
// 創(chuàng)建位置信息
CLLocationCoordinate2D center1 = CLLocationCoordinate2DMake(39.788857, 116.5559392);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center1 radius:500 identifier:@"經(jīng)海五路"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
// region 位置信息 repeats 是否重復(fù) (CLRegion 可以是地理位置信息)
UNLocationNotificationTrigger *locationTrigger = [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES];
2、創(chuàng)建推送的內(nèi)容(UNMutableNotificationContent)
UNNotificationContent:屬性readOnly
UNMutableNotificationContent:屬性有title滨溉、subtitle什湘、body、badge晦攒、sound闽撤、lauchImageName、userInfo脯颜、attachments哟旗、categoryIdentifier、threadIdentifier
本地消息內(nèi)容 |內(nèi)容限制大小 |展示
-------------|--------|
title |NSString| 限制在一行栋操,多出部分省略號(hào)
subtitle |NSString |限制在一行热幔,多出部分省略號(hào)
body| NSString |通知欄出現(xiàn)時(shí),限制在兩行讼庇,多出部分省略號(hào)绎巨;預(yù)覽時(shí),全部展示
**注意點(diǎn): **body中printf風(fēng)格的轉(zhuǎn)義字符蠕啄,比如說要包含%场勤,需要寫成%% 才會(huì)顯示,\同樣
// 創(chuàng)建通知內(nèi)容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此對(duì)象為不可變對(duì)象歼跟。
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"Dely 時(shí)間提醒 - title";
content.subtitle = [NSString stringWithFormat:@"Dely 裝逼大會(huì)競選時(shí)間提醒 - subtitle"];
content.body = @"Dely 裝逼大會(huì)總決賽時(shí)間到和媳,歡迎你參加總決賽!希望你一統(tǒng)X界 - body";
content.badge = @666;
content.sound = [UNNotificationSound defaultSound];
content.userInfo = @{@"key1":@"value1",@"key2":@"value2"};
3哈街、創(chuàng)建完整的本地推送請(qǐng)求Demo
//定時(shí)推送
+ (void)createLocalizedUserNotification{
// 設(shè)置觸發(fā)條件 UNNotificationTrigger
UNTimeIntervalNotificationTrigger *timeTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0f repeats:NO];
// 創(chuàng)建通知內(nèi)容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此對(duì)象為不可變對(duì)象留瞳。
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"Dely 時(shí)間提醒 - title";
content.subtitle = [NSString stringWithFormat:@"Dely 裝逼大會(huì)競選時(shí)間提醒 - subtitle"];
content.body = @"Dely 裝逼大會(huì)總決賽時(shí)間到,歡迎你參加總決賽骚秦!希望你一統(tǒng)X界 - body";
content.badge = @666;
content.sound = [UNNotificationSound defaultSound];
content.userInfo = @{@"key1":@"value1",@"key2":@"value2"};
// 創(chuàng)建通知標(biāo)示
NSString *requestIdentifier = @"Dely.X.time";
// 創(chuàng)建通知請(qǐng)求 UNNotificationRequest 將觸發(fā)條件和通知內(nèi)容添加到請(qǐng)求中
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger];
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
// 將通知請(qǐng)求 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];
//此處省略一萬行需求她倘。。作箍。硬梁。
}
}];
}
運(yùn)行結(jié)果如下:
二、 基本的遠(yuǎn)端推送
如果你想模擬遠(yuǎn)端推送胞得,按照我前面介紹的配置基本環(huán)境荧止、證書、push開關(guān)和基本方法就可以模擬遠(yuǎn)端的基本遠(yuǎn)端推送。
1跃巡、運(yùn)行工程則會(huì)拿到設(shè)備的Device Token危号,后面會(huì)用到。
2素邪、現(xiàn)在我們需要一個(gè)推送服務(wù)器給APNS發(fā)送信息葱色。我前面說了我花了12塊大洋(心疼死我了)買了一個(gè)APNS pusher 來模擬遠(yuǎn)端推送服務(wù),當(dāng)然你可以不花錢也可以用到娘香,例如:
NWPusher
3苍狰、你需要把你剛剛獲取的device token填到相應(yīng)位置,同時(shí)你要配置好push證書哦烘绽。
4淋昭、需要添加aps內(nèi)容了,然后點(diǎn)擊send就OK了
{
"aps" : {
"alert" : {
"title" : "iOS遠(yuǎn)程消息安接,我是主標(biāo)題翔忽!-title",
"subtitle" : "iOS遠(yuǎn)程消息,我是主標(biāo)題盏檐!-Subtitle",
"body" : "Dely,why am i so handsome -body"
},
"badge" : "2"
}
}
5歇式、稍縱即逝你就收到了遠(yuǎn)端消息了
6、Notification Management
對(duì)推送進(jìn)行查胡野、改材失、刪。都需要一個(gè)必需的參數(shù)requestIdentifier
1硫豆、更新通知
Local Notification需要通過更新request.相同的requestIdentifier龙巨,重新添加到推送center就可以了,說白了就是重新創(chuàng)建local Notification request(只要保證requestIdentifier就ok了)熊响,應(yīng)用場景如圖
Remote Notification 更新需要通過新的字段apps-collapse-id
來作為唯一標(biāo)示,我前面用的APNS pusher暫不支持這個(gè)字段旨别,不過github上有很多這樣的工具:
https://github.com/KnuffApp/Knuff
這樣remote 也可以更新推送消息
2、推送消息的查找和刪除
// Notification requests that are waiting for their trigger to fire
//獲取未送達(dá)的所有消息列表
- (void)getPendingNotificationRequestsWithCompletionHandler:(void(^)(NSArray<UNNotificationRequest *> *requests))completionHandler;
//刪除所有未送達(dá)的特定id的消息
- (void)removePendingNotificationRequestsWithIdentifiers:(NSArray<NSString *> *)identifiers;
//刪除所有未送達(dá)的消息
- (void)removeAllPendingNotificationRequests;
// Notifications that have been delivered and remain in Notification Center. Notifiations triggered by location cannot be retrieved, but can be removed.
//獲取已送達(dá)的所有消息列表
- (void)getDeliveredNotificationsWithCompletionHandler:(void(^)(NSArray<UNNotification *> *notifications))completionHandler __TVOS_PROHIBITED;
//刪除所有已送達(dá)的特定id的消息
- (void)removeDeliveredNotificationsWithIdentifiers:(NSArray<NSString *> *)identifiers __TVOS_PROHIBITED;
//刪除所有已送達(dá)的消息
- (void)removeAllDeliveredNotifications __TVOS_PROHIBITED;
測試如下:
+ (void)notificationAction{
NSString *requestIdentifier = @"Dely.X.time";
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
//刪除設(shè)備已收到的所有消息推送
// [center removeAllDeliveredNotifications];
//刪除設(shè)備已收到特定id的所有消息推送
// [center removeDeliveredNotificationsWithIdentifiers:@[requestIdentifier]];
//獲取設(shè)備已收到的消息推送
[center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
}];
}
段結(jié): 收到通知時(shí)你需要在appdelegate里面的代理方法里處理你的需求邏輯汗茄,這個(gè)需要你自己寫了秸弛。到目前為止你掌握了基本的本地推送和基本的遠(yuǎn)端推送!
不知不覺寫了這么多字(全是TM廢話)、本來繼續(xù)打算寫進(jìn)階的本地和遠(yuǎn)端推送(Media Attachments洪碳、Notification Actions递览、自定義推送界面等),留著下一篇博客繼續(xù)分享吧偶宫,欲知后事如何非迹,且聽下會(huì)裝X!
如果你喜歡可以點(diǎn)個(gè)喜歡_(竟有如此厚顏無恥之人)
下集預(yù)告:
參考資料:
https://developer.apple.com/reference/usernotifications
http://www.reibang.com/p/b74e52e866fc
http://www.reibang.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