其實,從 iOS8 以後,最大的改變是推播訊加了選項 (官方定義名稱為: Action 動作) 可以選擇,App 可以不需要在前景;使用者可以直接在推播訊息上,選擇你所定義好的選項,當使用者點擊了選項,系統會直接呼叫程式內的 handleActionWithIdentifier: 處理,即使 App 完全沒有在執行也可以。
在 iOS7 的 Remote Notification 如何工作。
首先,註冊直接呼叫指令 [UIApplication registerForRemoteNotificationTypes:]。
//註冊
- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types;
//Delegate
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
當註冊後,推播用的 token會經由 didRegisterForRemoteNotificationsWithDeviceToken: 傳送給手機內; 但若註冊失敗,則會由 didFailToRegisterForRemoteNotificationsWithError: 回報錯誤訊息。
再如何接收推播訊息呢?第一件必需清楚的是,若開啟 App 不是透過點擊推播訊息,才開啟App,App是收不到推播訊息的。
- 當App不在背景時,點擊推播訊息去開啟 App。推播訊息會分別由 didFinishLaunchingWithOptions: 和 didReceiveRemoteNotification: 帶入。
- 當App在背景時,點擊推播訊息去開啟 App。推播訊息只會由 didReceiveRemoteNotification: 帶入。
- 當App在前景時,此時推播訊息送達,推播訊息只會由 didReceiveRemoteNotification: 帶入。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
iOS8 多了Action 和 background handle
文章前頭有提到播推訊多了動作,可提供給使用者選擇。而這些動作就必需在程式內去定義好它們。另外一個功能,每次推播訊息需要提供的選項,不一定都是一致的。於是我們可以將動作分類,並將分類後,各個類別給與一個識別 (id)。推播伺服器推送訊息時,可以設定使用那個動作類別。
單純的呼叫 registerForRemoteNotificationTypes: 取得Token的方式將無法使用了。將拆解為
定義動作 (Action)
區分類別 (Category)
註冊 (若Location Notification 需要額外的 Core Location 註冊,在另外一篇討論)
定義動作 Action
新建一個使用者選項按鈕方法如下:
//來產生一個動作
UIMutableUserNotificationAction *actionLike = [[UIMutableUserNotificationAction alloc]init];
//決定這個動作,需不需要開啟App
actionLike.activationMode = UIUserNotificationActivationModeBackground;
//這個動作是否對資料或App會有破壞的程序。
actionLike.destructive = NO;
//這個動作是否需要使用者驗證。
actionLike.authenticationRequired = NO;
//動作的 id
actionLike.identifier = @"idLIKE";
//動作所顯示的文字
actionLike.title = @"喜歡";
區分類別
首先,先注意推播訊息會出現的四個位置,分別為 Lock screen、Notification center、Banner、和 Modal view。除了 Modal view 可以放三個動作外,其它位置僅能放二個動作。
//產生一個類別,並且給這個類別一個 id。
UIMutableUserNotificationCategory *catLike = [[UIMutableUserNotificationCategory alloc]init];
cat.identifier = @"LikeCategory";
//UIUserNotificationActionContextDefault,目前可放三個動作,而目前也只有給 Model view 用。
[cat setAction:@[actionLike, actionNoLike, actionHate] forContext:UIUserNotificationActionContextDefault];
//UIUserNotificationActionContextMinimal,目前可放二個動作,是較常使用的,除了 Modal view。
[cat setAction:@[actionLike, actionNoLike] forContext:UIUserNotificationActionContextMinimal];
可以註冊了。
//將所有的類別 category放在一個集合 (set),以產生一個UIUserNotificationSettings
NSSet *categories = [NSSet setWithArray:@[catLike, catAccept,...]];
UIUserNotificationSettings *settings =
[UIUserNotificationSettings
settingsForTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)
categories:categories];
//註冊,完成。結果依舊由 didRegisterForRemoteNotificationsWithDeviceToken 和 didFailToRegisterForRemoteNotificationsWithError 取得。
UIApplication *app = [UIApplication sharedApplication];
[app registerUserNotificationSettings:settings];
推播內容和處理
若推播訊息需要有提供選項給使用者,則在推播內容內,就需要指定 category。
{"aps":
{
"alert":"Do you like iPhone",
"category":"LikeCategory" //指定使用那個類別。
}
}
接收訊息和 iOS7 一樣,另外新增 handleActionWithIdentifier 函式,讓 App 不需要在前景,使用者點擊了動作,系統會呼叫這個函式。
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler;