03.iOS本地推送通知

@(〓〓 iOS-實用技術)[遠程/本地推送]


目錄

  • 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) 播放音效(提醒作用)
注意:以上樣式只能是用戶自己設置,我們無法通過代碼控制

  • 推送通知的展現示例圖
01.推送通知的展現示例圖.png

推送通知的分類

  • 本地推送通知

    • 應用場景: 確定知道未來某個時間點應該提醒用戶什么

    “本地”可以理解為”不聯網”;即使沒有網絡情況下,也可以推送通知消息

  • 遠程推送通知

    • 概念:

    與“本地”相對,表示,必須在聯網情況下才會向用戶推送通知消息
    遠程推送服務,又稱為APNs(Apple Push Notification Services)

    • 應用場景:
    1. 不確定未來某個時間點應該提醒用戶什么,臨時性的
    2. 當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提供一個文本行為)

監聽通知操作行為的點擊

// 監聽通知的點擊
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之后,必須推到后臺才能看到通知的運行效果.

首次運行會彈出讓用戶選擇授權

02.首次運行會彈出讓用戶選擇授權.png

在桌面頂部彈出效果

03.在桌面頂部彈出效果.png

下拉通知菜單的效果

04.下拉通知菜單的效果.png

本地通知的其他功能配置


設置時區跟隨手機系統時區

    // 設置時區跟隨手機系統時區
    localNotification.timeZone = [NSTimeZone defaultTimeZone];

設置通知的重復周期(最低一分鐘)

    // 設置通知的重復周期(最低一分鐘)
//    localNotification.repeatInterval = NSCalendarUnitMinute;


設置鎖屏狀態下, "滑動XXX"

    // 設置鎖屏狀態下, "滑動XXX"
    localNotification.hasAction = YES;
    localNotification.alertAction = @"alertAction";
  • 鎖屏狀態下, "滑動XXX"的運行效果
05.下拉通知菜單的效果.png

當通知進入鎖屏界面時, 滑動通知, 打開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;
  • 運行效果
06.應用程序圖片右上角的數字.png

通知傳值

    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;
}

  • 監聽通知的傳值運行效果圖
07.監聽通知的傳值運行效果圖.gif

監聽通知的點擊

  • 監聽本地通知的點擊
// ------------------------------------------------------------------------
/**
 只有當發送出一個本地通知, 并且滿足以下條件時, 才會調用該方法
 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.通知顯示文本框運行效果
08.通知顯示文本框運行效果.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容