iOS 10 came
在今年 6月14號 蘋果開發者大會 WWDC 2016 之后,筆者趕緊就去 apple 的開發者網站下載了最新的 Xcode 8 beta 和 iOS 10 beta ,然后在自己的手機上裝了 iOS 10 beta ,狠狠地體驗了一把。
可以說 iOS 10 無論從界面風格,還是 Framework 都做了很多改動。最直觀的感受就是界面的圓角增多了,系統動畫更加多樣和流暢,系統 App 的功能也變得更豐富了。
而 iOS 10 里的推送功能,也較之前更加強大,
今天我們就來聊聊 iOS 10 里的推送功能。
Notifications before iOS 10
首先我們一起簡單回顧下 iOS 10 以前的推送服務。
iOS 推送分為 Local Notifications(本地推送) 和 Remote Notifications(遠程推送),先看 2 張圖:
Local Notifications
Remote Notifications
簡單的說就是本地推送通過 App 本地定制,加入到系統的 Schedule 里,然后在指定的時間推送指定文字。而遠程推送通過服務端向蘋果推送服務器 Apple Push Notification Service (APNs) 發送 Notification Payload,之后 APNs 再將推送下發到指定設備的 指定 App 上。
以及 iOS 7 之后在不顯式地彈窗打擾用戶的情況下,進行的 靜默推送 :
Silent Push
具體做法可以參考 iOS 7 Background Remote Notification
User Notifications Framework
好,扯了這么多,該進入今天的正題了 —— User Notifications Framework 。
首先在 AppDelegate.m
中
import
#import lt;UserNotifications/UserNotifications.hgt;
注冊推送
以下分別是 iOS 10 之前和之后的注冊方式,其中的 UNAuthorizationOptions
里還可以找到 1 個 UNAuthorizationOptionCarPlay
的值是專為車載系統定制的值。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //iOS 10 before UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; //iOS 10 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error) { NSLog(@quot;request authorization succeeded!quot;); } }]; return YES; }
Notification settings
之前注冊推送服務,ios 8 及之前使用了不同的 API,并且返回結果也不同。現在 apple 不僅統一了這個 API,而且我們可以獲取到用戶更加詳細的設定了。
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { NSLog(@quot;%@quot;,settings); }];
打印獲得如下信息:
lt;UNNotificationSettings: 0x16567310; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, alertSetting: NotSupported, carPlaySetting: Enabled, alertStyle: Bannergt;
Token Registration
跟之前一樣
[[UIApplication sharedApplication] registerForRemoteNotifications];
Content
以前只能展示一條文字,現在可以有 title 、subtitle 以及 body 了。
定制方法如下:
//Local Notification UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @quot;Introduction to Notificationsquot;; content.subtitle = @quot;Session 707quot;; content.body = @quot;Woah! These new notifications look amazing! Don’t you agree?quot;; content.badge = @1; //Remote Notification { quot;apsquot; : { quot;alertquot; : { quot;titlequot; : quot;Introduction to Notificationsquot;, quot;subtitlequot; : quot;Session 707quot;, quot;bodyquot; : quot;Woah! These new notifications look amazing! Don’t you agree?quot; }, quot;badgequot; : 1 }, }
Triggers
又是一個新的功能,有三種
- UNTimeIntervalNotificationTrigger
- UNCalendarNotificationTrigger
- UNLocationNotificationTrigger
//2 分鐘后提醒 UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:120 repeats:NO]; //每小時重復 1 次喊我喝水 UNTimeIntervalNotificationTrigger *trigger2 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3600 repeats:YES]; //每周一早上 8:00 提醒我給老婆做早飯 NSDateComponents *components = [[NSDateComponents alloc] init]; components.weekday = 2; components.hour = 8; UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES]; //#import lt;CoreLocation/CoreLocation.hgt; //一到麥當勞就喊我下車 CLRegion *region = [[CLRegion alloc] init]; UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
Add Request
NSString *requestIdentifier = @quot;sampleRequestquot;; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:trigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
推送小結
然后整個推送的過程就變成了醬紫:
- Local Notifications 通過定義
Content
和Trigger
向UNUserNotificationCenter
進行request
這三部曲來實現。 - Remote Notifications 則向
APNs
發送Notification Payload
。
Notification Handling
設定了推送,然后就結束了?iOS 10 并沒有這么簡單!
通過實現協議,使 App 處于前臺時捕捉并處理即將觸發的推送:
@interface AppDelegate () lt;UNUserNotificationCenterDelegategt; -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{ completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound); }
讓它只顯示 alert 和 sound ,而忽略 badge 。
Notification Management
徹底掌控整個推送周期:
- Local Notification 通過更新 request
- Remote Notification 通過新的字段
apns-collapse-id
通過之前的 addNotificationRequest:
方法,在 id
不變的情況下重新添加,就可以刷新原有的推送。
NSString *requestIdentifier = @quot;sampleRequestquot;; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:newContent trigger:newTrigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
刪除計劃的推送:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
此外 UNUserNotificationCenter.h
中還有諸如 刪除所有推送、查看已經發出的推送、刪除已經發出的推送 等等強大的接口。
刷新原有的推送后,在通知中心的顯示里,也會有相應的變化,這里注意第 2 條信息,現在比分是 1:0
比分刷新后為 1:1,在不產生新的推送條目的情況下位置被前置了!
試想利用這個方法,不斷的刷新推送,是不是就可以做到讓自己 App 的推送內容始終展示在用戶手機通知中心的最頂端,力壓其余所有內容了呢?總感覺有點不厚道啊~
Advanced Notifications
關于推送的更多類似 Media Attachments
的高級功能,我們將在下一篇里詳細討論。
Media Attachments
為推送添加更多媒體附件,諸如圖片、音樂
繼續瀏覽下一篇 玩轉 iOS 10 推送 (中)
Tags: iOS開發
文章來源:http://www.jianshu.com/p/2f3202b5e758