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