ios中的通知和推送

推送通知

1、作用:讓不在前臺(後臺或者關閉)的APP知道APP內部發生的事情

2、在“設置”——>“通知中心”-----> 可以關閉推送通知

3、發送推送通知時,如果程序運行在前臺,推送通知就不會呈現。

4、點擊推送通知會打開對應的app

5、不管應用程序出於後臺還是被殺死,推送通知都會發出

一、本地推送通知
概念:由APP本身給應用程序推送消息,不需要服務器的支持
常見場景:記賬軟件/鬧鐘/定時提醒記賬/番茄工作法/系統電池沒電中提醒你時間等等
注意:不是非常常用。

1、發送本地推送

//點擊按鈕發送本地通知
- (IBAction)fireLocalNoti {
    //無論程序在前臺、後臺、退出了,都可以接收到本地通知
    //1.創建本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];
    
    //2.設置通知顯示的內容
    //2.1.設置通知發出的時間,即5秒後發出通知
    localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
    //2.2.設置通知的內容
    localNote.alertBody = @"喫飯了嗎?";
    //2.3.設置鎖屏界面滑塊下顯示的文字
    localNote.alertAction = @"聊天";
    //2.4.決定alertAction是否生效
    localNote.hasAction = NO;
    //2.5.設置通知中心的標題
    localNote.alertTitle = @"一般是app的名字";
    //2.6.設置通知時的音效
    localNote.soundName = UILocalNotificationDefaultSoundName;
    //2.7.設置app右上角的數字
    localNote.applicationIconBadgeNumber = 10;
    //2.8.設置額外的信息,暫時沒有用處
    localNote.userInfo = @{@"name":@"張三", @"age":@23};
    //2.9.本地通知的類型標誌符,做快捷回覆通知使用
    localNote.category = @"11";
    //2.10、通知重複調用的時間-->設置以後,則調度池不會自動銷燬通知
    localNote.repeatInterval = NSCalendarUnitMinute;
    
    
    //3.調度通知,讓通知在特定的時間發送本地通知,ios8.0以後纔出現
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
    
    //4、註冊通知,ios8.0,請求用戶權限的事情,如果只有一次,則在代碼直接在代碼處寫,多次在appDelegate中寫
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    
    //5、獲取本地通知,並刪除重複通知
    //獲取所有通知
//    NSArray *notifcationArr = [[UIApplication sharedApplication] scheduledLocalNotifications];
//    for (UILocalNotification *locationNoti in notifcationArr) {
//        //可以根據userInfo來刪除某個通知
//        if (locationNoti.userInfo) {
//            [[UIApplication sharedApplication] cancelLocalNotification:locationNoti];
//        }
//    }
}

- (IBAction)removeLocalNote {
    //關閉所有的通知
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

2、在前臺/後臺接收到通知後進行跳轉

//當(前臺/後臺)接收到一個本地通知時,會調用該方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    /**
     *  UIApplicationStateActive  前臺
     *  UIApplicationStateInactive  進入前臺
     *  UIApplicationStateBackground  後臺
     */
    if(application.applicationState == UIApplicationStateActive){
        NSLog(@"在前臺時,不要進行跳轉;要麼提示用戶進行跳轉");
        //當然也可以跳轉到指定界面
        return;
    }
    //在後臺進入前臺時,跳轉到某個固定的頁面
    NSLog(@"根據%@跳轉到一個固定的頁面:%s", notification.userInfo, __func__);
}

3、在應用程序被殺死時,接收到本地推送通知後進行跳轉

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0){
        //1.iOS8之後,如果想要發出通知(無論本地還是遠程),必須先進行註冊.(iOS8之前不需要)
        UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
        [application registerUserNotificationSettings:setting];
    }else{
        
        //ios8.0之前的註冊推送通知
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    }
    
    //如果應用程序被殺死了,但是任然要實現接收到通知進行跳轉,則需要在此處實現跳轉。因爲程序被殺死後,接收到通知不會調用didReceiveLocalNotification方法。
    // 判斷是否是通過點擊通知打開了應用程序
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 跳轉代碼
        NSLog(@"接收到本地通知,跳轉到一個固定的界面");
    }
    return YES;
}

4、本地推送快捷回覆調用的方法

通過分類來實現

//無論程序在前臺、後臺、退出了,都可以接收到本地通知
    //1.創建本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];
    
    //2.9.本地通知的類型標誌符
    localNote.category = @"category";

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //1、創建本地推送通知分類
    UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
    //2、設置標誌符
    category.identifier = @"category";
    
    //3、設置前臺按鈕
    UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
    action1.identifier = @"qiantai";
    //3.1、設置前臺按鈕模式
    action1.activationMode = UIUserNotificationActivationModeForeground;
    //3.2、設置按鈕的標題
    action1.title = @"qiantai哈哈";
    
    
    //3、設置後臺按鈕
    UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
    action2.identifier = @"houtai";
    //3.1、設置前臺按鈕模式
    action2.activationMode = UIUserNotificationActivationModeBackground;
    //3.2、設置按鈕的標題
    action2.title = @"houtai哈哈";
    
    
    //4、設置按鈕
    [category setActions:@[action1, action2] forContext:UIUserNotificationActionContextDefault];
    
    //5、設置分類的集合
    NSSet *categorySet = [NSSet setWithObject:category];
    
    
    
    
    if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0){
        //1.iOS8之後,如果想要發出通知(無論本地還是遠程),必須先進行註冊.(iOS8之前不需要)
        /**
         *  @param types:顯示收到本地通知時的樣式
         *         UIUserNotificationTypeNone  無
         *         UIUserNotificationTypeBadge  app圖像顯示通知的數字
         *         UIUserNotificationTypeSound  聲音
         *         UIUserNotificationTypeAlert  彈窗
         *
         */
        //6、設置分類集合
        UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categorySet];
        [application registerUserNotificationSettings:setting];
    }else{
        
        //ios8.0之前的註冊推送通知
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    }

    return YES;
}

//處理分類按鈕調用的方法
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
    
    NSLog(@"根據標識符進行邏輯操作%@", identifier);
    
    //一旦接收到本地推送通知,必需調用,告訴系統進行資源分配
    completionHandler();
    
}









二、遠程推送

1、概念

概念:由服務器推送消息給用戶,彈出消息的通知(需要聯網),需要服務器的支持。遠程推送服務,又稱爲APNs(Apple PushNotification Services)。
常見場景:微信提醒新消息/淘寶提醒有新活動/視頻軟件提供您有最新電影
注意:非常常用.但是如果僅僅是給用戶提醒,客戶端(你)做的事情就非常簡單.
 
例子:淘寶最近雙11搞活動,各種送紅包,想告知用戶.但是該用戶不經常打包淘寶APP.淘寶如何通知該用戶有最新的活動呢?
傳統方式(以前):只有用戶打開了淘寶客戶端,客戶端向服務器請求是否有最新的活動,才能在APP中告知用戶活動。
傳統方式侷限性:只要用戶關閉了app,就無法跟app的服務器溝通,無法從服務器上獲得最新的數據內容。
遠程推送通知的好處:不管用戶打開還是關閉app,只要聯網了,都能接收到服務器推送的遠程通知。

 

2、原理
遠程通知的原理:淘寶服務器把“紅包活動” --> 推送 -->  蘋果的APNs服務器  --> 推送 --> 淘寶客戶端app
 


2.1、爲什麼淘寶服務器不直接推消息給用戶?
在通常情況下服務器端是不能主動向客戶端推消息的。
如果想服務器端給客戶端推消息,必須建立長連接,淘寶客戶端在處於後臺時不能和服務器端建立長連接。

2.2、爲什麼蘋果服務器可以推消息給用戶?
所有的蘋果設備,在聯網狀態下,都會與蘋果的服務器建立長連接
蘋果建立長連接的作用:時間校準、系統升級提示、查找我的iPhone、遠程推送通知


短鏈接:客戶端app給服務器發送請求,服務器返回數據,客戶端app收到數據,鏈接斷開。此時,服務器則不能給客戶端推送消息。
長鏈接:通過socket來建立。即時通訊中使用。建立長鏈接對服務器的負荷特別大。高併發後臺人才的技術,可以節省服務器。

2.3、蘋果在推送消息時,如何準確的推送給某一個用戶,並且知道是哪一個APP?
在淘寶服務器把消息給蘋果的APNs服務器時,必須告知蘋果DeviceToken
什麼是DeviceToken?
DeviceToken是由用戶手機的UDID和應用程序的BundleID共同生成的
通過DeviceToken可以找到唯一手機中的唯一應用程序
如何獲得DeviceToken?
客戶端到蘋果的APNs註冊即可獲得。

2.4、如何實現遠程推送通知
首先,BundleID對應的APPID必須是明確的(特殊功能)
該APPID必須配置兩個證書
調試證書:用於調試遠程推送
發佈證書:用於發佈後給用戶推送消息
根據上面的APPID重新配置描述文件
安裝對應的證書,即可開始測試遠程推送

3、蘋果自帶的遠程推送通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    if([[UIDevice currentDevice].systemVersion doubleValue]>= 8.0){
        //註冊推送通知
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
        
        [application registerUserNotificationSettings:settings];
        
        //註冊遠程通知,獲取DeviceToken
        [application registerForRemoteNotifications];
        
    }else{
        
        //ios8.0之前的註冊推送通知
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    }
    
    //如果應用程序被殺死了,但是任然要實現接收到通知進行跳轉,則需要在此處實現跳轉。因爲程序被殺死後,接收到通知不會調用didReceiveRemoteNotification方法。
    // 判斷是否是通過點擊通知打開了應用程序
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 跳轉代碼
        NSLog(@"接收到本地通知,跳轉到一個固定的界面");
        //獲取通知的消息
        NSDictionary *remoteDict = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
        
    }
    
    return YES;
}

//通過代理方法獲取deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    
    //deviceToken:用於發送給公司的服務器,讓公司的服務器作存儲
    NSLog(@"%@", deviceToken);
    
    /**
     *  UIApplicationStateActive  前臺
     *  UIApplicationStateInactive  進入前臺
     *  UIApplicationStateBackground  後臺
     */
    if(application.applicationState == UIApplicationStateActive){
        NSLog(@"在前臺時,不要進行跳轉");
        return;
    }
    NSLog(@"跳轉到一個固定的頁面:%s", __func__);
}

#pragma mark - 當接收到遠程推送時,調用該方法
//前臺/後臺時,可以在此方法接收到通知,在殺死時需要在didFinishLaunchingWithOptions
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    NSLog(@"%@", userInfo);
}

#pragma mark - 當接收到遠程推送時,調用該方法,ios7推出
//前臺/後臺/退出時,可以在此方法接收到通知
//如果此方法和“application:didReceiveRemoteNotification:”方法都實現,則此方法有效,另外一個方法無效
//如果實現了此方法,還需要打開一個選項值 --> 點擊項目 --> capabilites --> backgroundModes --> remoteNotification,即打開了後臺遠程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    
    //必須調用一下block,否則報錯。此block告訴蘋果服務器推送是否成功
//    UIBackgroundFetchResultNewData
//    UIBackgroundFetchResultNoData
//    UIBackgroundFetchResultFailed
    completionHandler(UIBackgroundFetchResultNewData);
}

三、第三方平臺的遠程推送通知

友盟、極光推送

推送的作用非常簡單,就是將我們服務器需要做的事情用激光推送服務器作爲替代。

極光推送給任何用戶不需要交錢,但是如果推送給特定的用戶則需要交錢。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章