@(〓〓 iOS-實用技術)[遠程/本地推送]
- 作者: Liwx
- 郵箱: 1032282633@qq.com
目錄
- 03.iOS本地推送通知
- 1.推送通知簡介
- 什么是推送通知?
- 推送通知的分類
- 2.本地推送通知
- 本地通知的基本使用
- 額外設置/通知調度
- 監聽用戶點擊通知
- 額外補充
- 監聽通知操作行為的點擊
- 3.本地通知的使用
- 本地通知的基本使用
- 本地通知的其他功能配置
- 設置時區跟隨手機系統時區
- 設置通知的重復周期(最低一分鐘)
- 設置鎖屏狀態下, “滑動XXX”
- 當通知進入鎖屏界面時, 滑動通知, 打開APP時, 彈出的啟動界面(現在設置這個屬性沒有效果)
- 設置通知的彈框標題(iOS 8.2之后)
- 設置通知的提示聲音
- 設置應用程序圖片右上角的數字(取消直接設置為0)
- 通知傳值
- 獲取所有計劃的通知
- 取消所有計劃的通知
- 補充
- 4.監聽通知的點擊
- 通知非正常啟動時傳值
- 監聽通知的點擊
- 通知顯示文本框(iOS 9.0之后才能使用)
1.推送通知簡介
什么是推送通知?
首先明確:此處的推送通知跟”NSNotification”并沒有任何關系
可以理解為: 向用戶推送一條信息來通知用戶某件事情
作用: 可以在APP退到后臺,或者關閉時;繼續推送一條消息告訴用戶某件事情
- 推送通知的應用場景?
(1) 一些任務管理APP,會在任務時間即將到達時,通知你做該任務;
(2) 健身App定時提醒你應該健身了;
(3) 買過電影票后,提前半小時告訴你,電影即將開場;
(4) 當你QQ或者微信收到消息時,即使退到后臺,或者關閉APP,也可以收到信息通知告訴我們;
(5) 電商APP,推送一條消息通知我們有新品上架等等
- 推送通知的展現樣式
(1) 在屏幕頂部顯示一塊橫幅(顯示具體內容)
(2) 在屏幕中間彈出一個UIAlertView(顯示具體內容)
(3) 在鎖屏界面顯示一塊橫幅(鎖屏狀態下,顯示具體內容)
(4) 更新app圖標的數字(說明新內容的數量)
(5) 播放音效(提醒作用)
注意
:以上樣式只能是用戶自己設置,我們無法通過代碼控制
- 推送通知的展現示例圖
推送通知的分類
-
本地推送通知
- 應用場景: 確定知道未來某個時間點應該提醒用戶什么
“本地”可以理解為”不聯網”;即使沒有網絡情況下,也可以推送通知消息
-
遠程推送通知
- 概念:
與“本地”相對,表示,必須在聯網情況下才會向用戶推送通知消息
遠程推送服務,又稱為APNs(Apple Push Notification Services)- 應用場景:
- 不確定未來某個時間點應該提醒用戶什么,臨時性的
- 當APP徹底退出時也想繼續讓用戶獲取一些最新消息
使用原則: 誰能確定通知時間和內容, 誰就可以發送(開發人員在APP內部通過代碼發送=本地通知; 服務器可以確定通知時間和內容=遠程通知)
2.本地推送通知
本地通知的基本使用
1.創建UILocalNotification 對象
-
2.設置一些必要屬性
推送通知的觸發時間
(何時發出推送通知)
@property(nonatomic,copy) NSDate *fireDate;
推送通知的具體內容
@property(nonatomic,copy) NSString *alertBody; -
3.開始推送通知
根據fireDate設定的時間進行推送
[[UIApplication sharedApplication] scheduleLocalNotification:ln];
立即推送
presentLocalNotificationNow:(UILocalNotification *)notification; -
4.注意事項
-
在iOS 8.0+
,如果要使用本地通知,需要得到用戶的許可
-
// 在didFinishLaunchingWithOptions方法中添加如下代碼
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
額外設置/通知調度
- 通知的配置
// 每隔多久重復發一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval;
// 點擊推送通知打開app時顯示的啟動圖片
@property(nonatomic,copy) NSString *alertLaunchImage;
// 附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo;
// 時區(一般設置為[NSTimeZone defaultTimeZone] ,跟隨手機的時區)
@property(nonatomic,copy) NSTimeZone *timeZone;
// 在鎖屏時顯示的動作標題(完整標題:“滑動來” + alertAction)
@property(nonatomic,copy) NSString *alertAction;
// 音效文件名
@property(nonatomic,copy) NSString *soundName;
// app圖標數字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
- 取消調度本地推送通知
// 取消指定本地推送通知
- (void)cancelLocalNotification:(UILocalNotification *)notification;
// 取消所有本地推送通知
- (void)cancelAllLocalNotifications;
- 獲得被調度(定制)的所有本地推送通知
// 已經發出且過期的推送通知就算調度結束,會自動從這個數組中移除
@property(nonatomic,copy) NSArray *scheduledLocalNotifications;
監聽用戶點擊通知
-
app處于前臺
此時不會彈框通知用戶通知的到達,但是還是會調用對應的代理方法
-
app并沒有關閉,一直隱藏在后臺時
此時用戶點擊通知信息后,會讓app進入前臺,并會調用AppDelegate的下面方法
application: didReceiveLocalNotification: -
app已經被關閉(進程已死)
此時用戶點擊通知信息后,會啟動app,啟動完畢會調用AppDelegate的下面方法
application: didFinishLaunchingWithOptions:
launchOptions參數通過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象
額外補充
在iOS8.0之后,可以設置推送通知帶操作行為
-
在注冊設置時,設置categories:參數
-
UIMutableUserNotificationAction
- identifier
動作標識
- title
動作標題
- activationMode
是前臺運行, 還是后臺運行此動作
- destructive
是否是破壞性動作
(只是通過顏色, 標識按鈕, 給用戶提示) - behavior
動作行為
(iOS9.0提供一個文本行為)
- identifier
-
監聽通知操作行為的點擊
// 監聽通知的點擊
application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void)
// 監聽通知的點擊(優先級較高)iOS 9.0以后可以使用的方法,如果該方法實現,就不會調用上面的方法.
application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void)
3.本地通知的使用
本地通知的基本使用
- 1.請求授權(iOS 8.0之后需主動請求授權)
- 在AppDelegate.m中請求授權
// ----------------------------------------------------------------------------
// iOS 8.0之后需主動請求授權
- (void)requestAuthor
{
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// 設置通知的類型可以為彈窗提示,聲音提示,應用圖標數字提示
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
// 授權通知
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 主動請求授權
[self requestAuthor];
return YES;
}
- 2.在ViewController.m中設置本地通知的屬性
- 發送方式一: 根據通知的發送時間(fireDate)發送通知
- 發送方式二: 立即發送通知
// 如果是iOS 8.0之前版本,不用請求授權就能發送本地通知.如果是iOS 8.0之后,需主動請求授權才能發送本地通知.一般在AppDelegate中請求授權
// 1.通知顯示的條件:
// 1.1 當App處于后臺,鎖屏狀態,徹底退出時,都會顯示通知
// 注意: 當App處于前臺狀態時,不會顯示通知
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 1.創建通知
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
// 2.設置通知的必選參數
// 設置通知顯示的內容
localNotification.alertBody = @"本地通知測試";
// 設置通知的發送時間
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
// 3.發送通知
// 方式一: 根據通知的發送時間(fireDate)發送通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// 方式二: 立即發送通知
// [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
- 3.運行效果圖
-
注意
: 運行程序后,點擊view之后,必須推到后臺才能看到通知的運行效果.
-
首次運行會彈出讓用戶選擇授權
在桌面頂部彈出效果
下拉通知菜單的效果
本地通知的其他功能配置
設置時區跟隨手機系統時區
// 設置時區跟隨手機系統時區
localNotification.timeZone = [NSTimeZone defaultTimeZone];
設置通知的重復周期(最低一分鐘)
// 設置通知的重復周期(最低一分鐘)
// localNotification.repeatInterval = NSCalendarUnitMinute;
設置鎖屏狀態下, "滑動XXX"
// 設置鎖屏狀態下, "滑動XXX"
localNotification.hasAction = YES;
localNotification.alertAction = @"alertAction";
- 鎖屏狀態下, "滑動XXX"的運行效果
當通知進入鎖屏界面時, 滑動通知, 打開APP時, 彈出的啟動界面(現在設置這個屬性沒有效果)
// 當通知進入鎖屏界面時, 滑動通知, 打開APP時, 彈出的啟動界面
// 注意: 現在這個屬性, 沒有反應!!!!
localNotification.alertLaunchImage = @"bear";
設置通知的彈框標題(iOS 8.2之后)
// 設置通知的彈框標題
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.2) {
localNotification.alertTitle = @"alertTitle";
}
設置通知的提示聲音
// 設置通知的提示聲音 UILocalNotificationDefaultSoundName: 系統默認聲音
// 注意: 手機必須處于非靜音模式!!!
localNotification.soundName = @"win.aac";
設置應用程序圖片右上角的數字(取消直接設置為0)
// 設置應用程序圖片右上角的數字(如果想要取消右上角的數字, 直接把這個參數值為0)
localNotification.applicationIconBadgeNumber = 10;
- 運行效果
通知傳值
localNotification.userInfo = @{@"name" : @"liwx", @"body" : @"吃飯了沒呀~~~"};
獲取所有計劃的通知
// 獲取所有計劃的通知
NSArray *array = [UIApplication sharedApplication].scheduledLocalNotifications;
取消所有計劃的通知
// 取消所有計劃的通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
補充
- 應用程序進入前臺會調用該代理方法
// 進入前臺時會調用該方法
- (void)applicationDidBecomeActive:(UIApplication *)application;
4.監聽通知的點擊
通知非正常啟動時傳值
- App非正常啟動時,通知傳值
當App完全關閉后,點擊通知進入App啟動時,會將通知的參數傳遞給
launchOptions
- 監聽通知的傳值launchOptions參考代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 主動請求授權
[self requestAuthor];
// ------------------------------------------------------------------------
// 如果當APP通過一些非正常手段啟動時(正常: 點擊APP 圖標打開)
// 這時候, 都會把對應的一些參數信息, 傳遞給launchOptions
// 此處不能使用NSLog打印,NSLog只能在調試狀態下打印,而此方式必須應用完全關閉,所有不是出于調試狀態.所以此處使用TextView來顯示launchOptions的值
NSLog(@"launchOptions: %@", launchOptions);
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(200, 150, 150, 480)];
textView.backgroundColor = [UIColor orangeColor];
textView.text = launchOptions.description;
[self.window.rootViewController.view addSubview:textView];
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
textView.text = [NSString stringWithFormat:@"%@, ------\n%@", textView.text, @"用戶是通過點擊了通知啟動的APP"];
}
return YES;
}
- 監聽通知的傳值運行效果圖
監聽通知的點擊
- 監聽本地通知的點擊
// ------------------------------------------------------------------------
/**
只有當發送出一個本地通知, 并且滿足以下條件時, 才會調用該方法
APP 處于前臺情況
當用用戶點擊了通知, 從后臺, 進入到前臺時,
當鎖屏狀態下, 用戶點擊了通知, 從后臺進入前臺
注意: 當App徹底退出時, 用戶點擊通知, 打開APP , 不會調用這個方法
但是會把通知的參數傳遞給 application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
*/
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"接收到本地通知");
// 通過UI控件來測試.當App徹底退出時, 用戶點擊通知, 打開APP , 會不會調用這個方法
UISwitch *sw = [[UISwitch alloc] init];
[self.window.rootViewController.view addSubview:sw];
// 查看當前的狀態出于(前臺: 0)/(后臺: 2)/(從后臺進入前臺: 1)
NSLog(@"applicationState.rawValue: %zd", application.applicationState);
// 執行響應操作
// 如果當前App在前臺,執行操作
if (application.applicationState == UIApplicationStateActive) {
NSLog(@"執行前臺對應的操作");
} else if (application.applicationState == UIApplicationStateInactive) {
// 后臺進入前臺
NSLog(@"執行后臺進入前臺對應的操作");
NSLog(@"%@", notification.userInfo);
} else {
// 當前App在后臺
NSLog(@"執行后臺對應的操作");
}
}
通知顯示文本框(iOS 9.0之后才能使用)
- 1.創建本地通知行為操作組
- UIMutableUserNotificationCategory: 行為操作組
- UIMutableUserNotificationAction: 行為操作按鈕
- identifier: 行為操作標識
- title: 行為操作按鈕的標題
- behavior: 設置通知提醒顯示文本框
UIUserNotificationActionBehaviorTextInput
.(iOS 9.0之后才能使用) - activationMode: 設置行為操作按鈕點擊后是在前臺還是后臺運行
- authenticationRequired: 設置只有解鎖之后才能執行
- destructive: 設置這個操作是否是破壞性的行為(通過不同顏色來區別)
- 使用步驟: 將按鈕添加到操作組,之后將操作組封裝到集合.封裝的集合左右請求授權的參數.具體操作參考以下代碼.
// ----------------------------------------------------------------------------
// iOS 8.0之后需主動請求授權
- (void)requestAuthor
{
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// ------------------------------------------------------------------------
// 1.給通知設置一些操作行為.注意: 需先注冊這些操作行為
// 1.1 創建一個組
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
// 設置組的標識
category.identifier = @"select";
// ------------------------------------------------------------------------
// 添加按鈕1 "進入"
// 1.2 創建操作行為
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
// 設置行為的標識
action1.identifier = @"go";
action1.title = @"進入";
// action1.behavior = nil;
// 設置要在前臺執行該行為
action1.activationMode = UIUserNotificationActivationModeForeground;
// 設置只有解鎖之后才能執行
// action1.authenticationRequired = YES;
// 設置這個操作是否是破壞性的行為(通過不同顏色來區別)
action1.destructive = YES;
// ------------------------------------------------------------------------
// 添加按鈕2 "回復"
// 1.2 創建操作行為
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
// 設置行為的標識
action2.identifier = @"answer";
action2.title = @"回復";
// iOS 9.0之后才能彈出文本框,如果沒判斷,在9.0之前版本運行,程序會崩潰
if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
action2.behavior = UIUserNotificationActionBehaviorTextInput;
}
// 設置要在后臺執行該行為
action2.activationMode = UIUserNotificationActivationModeBackground;
// 設置這個是破壞性的行為(通過不同顏色來區別)
action2.destructive = NO;
// ------------------------------------------------------------------------
// 將按鈕1和按鈕2添加到category
NSArray *actions = @[action1, action2];
[category setActions:actions forContext:UIUserNotificationActionContextDefault];
// 將category封裝為集合
NSSet *categories = [NSSet setWithObjects:category, nil];
// ------------------------------------------------------------------------
// 授權通知
// 設置通知的類型可以為彈窗提示,聲音提示,應用圖標數字提示
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categories];
// 授權通知
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
}
- 2.
注意
: 在創建本地通知時必須指定
通知使用哪個操作組
// 指定通知使用哪個操作組
localNotification.category = @"select";
- 3.通知顯示文本框運行效果