iOS 本地通知和遠程推送
推送通知的應用纹烹,可以推送最新的消息給用戶,獲得更多的關注召边。
推送分為本地推送和遠程推送兩種铺呵。并且在 iOS 8.0之后做了相關的改變。iOS 8.0之后不管是遠程推送還是本地推送隧熙,都需要執(zhí)行一個注冊方法片挂。
// 通知類型,顯示未讀信息標志, 顯示提示通知音念,播放聲音滋将。
UIUserNotificationType notificationType = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
// 設置通知類型和執(zhí)行動作
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
// 注冊通知
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
在調(diào)用此方法之后, 若是第一次調(diào)用注冊症昏,則會彈出是否允許此應用發(fā)送通知随闽。并會調(diào)用 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
方法。
在此方法中做操作肝谭。
本地通知
創(chuàng)建本地通知
- (void)sendLocalNotifi {
// 添加本地通知
UILocalNotification *localNoti = [[UILocalNotification alloc] init];
NSDate *Date = [NSDate date];
localNoti.fireDate = Date; // 發(fā)送通知時間 這里沒做具體處理掘宪,若是要推送時間無誤差,時間要精確到秒攘烛。
localNoti.timeZone = [NSTimeZone localTimeZone]; // 設置時區(qū) 默認時區(qū)
localNoti.repeatInterval = NSCalendarUnitSecond; // 發(fā)送通知的間隔
localNoti.alertTitle = @"通知"; // 彈窗title
localNoti.alertBody = @"起來搬磚了N汗觥!"; // 彈窗body顯示內(nèi)容
localNoti.soundName = UILocalNotificationDefaultSoundName;
localNoti.alertLaunchImage = @"1.jpg"; // 用于點擊啟動顯示啟動頁坟漱,必須是 UILaunchImageFile
localNoti.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"value", @"key", nil];
// localNoti.soundName = @"1"; // 響鈴音樂文件名稱鼠次, 放在main bundle 里邊
localNoti.applicationIconBadgeNumber = 2; // app 的未讀消息個數(shù)
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[[UIApplication sharedApplication] scheduleLocalNotification:localNoti]; // 按照指定時間發(fā)送通知
// [[UIApplication sharedApplication] presentLocalNotificationNow:localNoti]; // 立即發(fā)送通知
}
在注冊回調(diào)方法中
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
// 判斷若 types 不為 UIUserNotificationTypeNone 這可以添加本地通知
if (notificationSettings.types != UIUserNotificationTypeNone) {
[self sendLocalNotifi]; // 當然設置本地推送的方法不一定要要放在這里。 這僅僅是個例子芋齿。
}
}
以上獲得通知為最基本的通知腥寇,提示作用, 若是要有比如回復等操作觅捆, 則需要添加相應的 action
方法赦役。
// 添加動作
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
action1.identifier = @"1"; // 標示用于區(qū)分點擊的哪個按鈕。
action1.title = @"OK";
action1.activationMode = UIUserNotificationActivationModeForeground;
// UIUserNotificationActivationModeForeground 在前臺處理事件栅炒,則在處理此事件時掂摔,系統(tǒng)會把 app 切換到前臺。
// UIUserNotificationActivationModeBackground 在后臺處理事件赢赊,點擊事件在后臺處理乙漓,不需要使app 切換到前臺狀態(tài),
action1.destructive = NO;
action1.authenticationRequired = NO;
action1.behavior = UIUserNotificationActionBehaviorDefault;
/*
UIUserNotificationActionBehaviorTextInput // 輸入框樣式
UIUserNotificationActionBehaviorDefault // 默認樣式
*/
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
action2.identifier = @"2";
action2.title = @"cacel";
action2.activationMode = UIUserNotificationActivationModeForeground;
action2.destructive = NO; //
action2.authenticationRequired = NO;
// 設置擴展 Categories
UIMutableUserNotificationCategory *catergory = [[UIMutableUserNotificationCategory alloc] init];
catergory.identifier = @"localCatergory"; // 設置識別的標示符
[catergory setActions:@[action1, action2] forContext:UIUserNotificationActionContextMinimal];
[catergory setActions:@[action2, action1] forContext:UIUserNotificationActionContextDefault];
// 別忘了給添加的本地通知添加擴展的識別符
- (void)sendLocalNotifi {
................
localNoti.category = @"localCatergory";
}
// 在第一步注冊的時候別忘了 categories
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
categories:[NSSet setWithObjects:catergory, nil]];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
注冊完成释移,回調(diào)方法叭披。當app處于活躍狀態(tài)的時候, 會調(diào)用以下代理方法- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
秀鞭,開著的狀態(tài)可以調(diào)用此方法進行處理 趋观。
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSDictionary *infoDic = notification.userInfo;
NSLog(@"%@", infoDic);
}
若是在后臺或者關閉app的狀態(tài),如下圖所示,這不同的點擊方法則會走不同的方法锋边。
- 若點擊對應的動作這回調(diào)用
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler
方法對不同的按鈕分別進行判別皱坛,以進行不同的處理。
此方法為iOS8.0 方法豆巨, 若是iOS 9.0 之后剩辟,可以執(zhí)行- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler
方法進行判別處理相應的操作。但別忘了在方法最后執(zhí)行 completionHandler(); 以告訴系統(tǒng)已經(jīng)處理完畢。
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:@"accept_action"]) {
NSLog(@"-----accept action");
} else if ([identifier isEqualToString:@"cancel_action"]) {
NSLog(@"-----cancel action");
}
if (completionHandler) {
completionHandler();
}
}
-
若點擊顯示信息的區(qū)域贩猎,未點擊 action 按鈕熊户, 若app只是在后臺,系統(tǒng)則會把app 轉(zhuǎn)化為前臺狀態(tài)吭服,并在
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
方法中啟用操作嚷堡, 但若是app是關閉狀態(tài), 這系統(tǒng)- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
初始化方法中艇棕,在launchOptions
中通過鍵值對獲取到對應的消息蝌戒。- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ UILocalNotification * localNotify = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; return YES; }
-
取消本地通知
// 取消所有本地通知 [[UIApplication sharedApplication] cancelAllLocalNotifications]; [[UIApplication sharedApplication] cancelLocalNotification:localNoti];
遠程推送
遠程推送的 Action 和 Categories 以及 Settings 與上邊的設置一樣。
不一樣的地方在于接受的方法沼琉。
遠程推送北苟,所有消息大小不超過2KB,我們獲取遠程推送的json格式的消息,解析這個消息就是我們的遠程推送了;
在注冊的回調(diào)方法中打瘪,
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
if (notificationSettings.types != UIUserNotificationTypeNone) {
[application registerForRemoteNotifications];
}
}
在獲取遠程推送成功之后友鼻,APNs 服務器會返回一個 deviceToken,如果是自己家的服務器闺骚,則需要獲取到相應的 deviceToken 返回到自身的服務器彩扔,以方便后臺的服務器做推送使用。若是用第三方的葛碧,則需要包 deviceToken 發(fā)送給第三方借杰。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// 注冊遠程通知成功之后,會接收到 APNs 服務器的 deviceToken
}
獲取 deviceToken 失敗調(diào)用进泼, 可以重新發(fā)送注冊遠程推送請求。
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
// 獲取 device token 失敗纤虽, 則會回調(diào)此方法乳绕,并報出錯誤
if(error){
[application registerForRemoteNotifications];
}
}
以下幾個方法和本地通知方法類似
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// 接收到遠程通知信息
}
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
{
//在沒有啟動本App時,收到服務器推送消息逼纸,下拉消息會有快捷回復的按鈕洋措,點擊按鈕后調(diào)用的方法,根據(jù)identifier來判斷點擊的哪個按鈕
completionHandler();
}
// iOS 9.0 之后的方法杰刽, 和上邊的方法類似菠发,但多個參數(shù)更方便操作
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler {
completionHandler();
}
// 若是點擊重新啟動app
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSDictionary * userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
return YES;
}
-
如何實現(xiàn)遠程推送的時候,設置Categories贺嫂,以便系統(tǒng)找到對應的Categories來實現(xiàn) action 操作滓鸠。這需要在推送的消息格式中添加相應的字段來識別。當 推送消息到達用戶時第喳, iOS能識別這個類別的鍵值對糜俗,并查找到與之對應的注冊的通知,并顯示相應的操作, 添加的字段如下:
{ "aps" : { "alert" : "You’re invited!", "category" : "INVITE_CATEGORY" } }