第一步: 導入 #import
且要遵守
這裡需要注意,我們最好寫成這種形式(防止低版本找不到頭文件出現問題)
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import
#endif
第二步:我們需要在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中注冊通知,代碼如下
- (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];
}
上面需要注意:
之前注冊推送服務,用戶點擊了同意還是不同意,以及用戶之後又做了怎樣的更改我們都無從得知,現在 apple 開放了這個 API,我們可以直接獲取到用戶的設定信息了。注意UNNotificationSettings是只讀對象哦,不能直接修改!只能通過以下方式獲取
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"========%@",settings);
}];
打印信息如下: ========
4、 遠端推送需要獲取設備的Device Token的方法是沒有變的,代碼如下
#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個代理方法來處理通知的接收和點擊事件,這兩個方法在
此外,蘋果把本地通知跟遠程通知合二為一。區分本地通知跟遠程通知的類是
UNPushNotificationTrigger.h類中,
UNPushNotificationTrigger的類型是新增加的,通過它,我們可以得到一些通知的觸發條件 ,解釋如下:
UNPushNotificationTrigger (遠程通知) 遠程推送的通知類型
UNTimeIntervalNotificationTrigger (本地通知) 一定時間之後,重復或者不重復推送通知。我們可以設置timeInterval(時間間隔)和repeats(是否重復)。
UNCalendarNotificationTrigger(本地通知) 一定日期之後,重復或者不重復推送通知 例如,你每天8點推送一個通知,只要dateComponents為8,如果你想每天8點都推送這個通知,只要repeats為YES就可以了。
UNLocationNotificationTrigger (本地通知)地理位置的一種通知,
當用戶進入或離開一個地理區域來通知。現在先提出來,後面我會一一代碼演示出每種用法。還是回到兩個很吊的代理方法吧
#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.下面這個代理方法,只會是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);