天天看點

iOS開發-本地通知與遠端通知

App開發中經常會使用到推送,蘋果和安卓差別是蘋果用自己的APNS推送伺服器,不論我們是內建第三方推送 

還是用蘋果系統的推送都要經過APNS推送伺服器。

目前市場上比較流行的幾個第三方推送:

1.極光推送 (使用較多,但是偶爾會出現crash,crash定位在jPush SDK沒法解決,會出現推送延遲的情況)

2.阿裡雲推送(推出時間較短,目前可能會出現一些問題,支援全量推送、裝置号推送、賬号推送,注意阿裡雲推送推送消息和推送通知走的是兩個不同的接口,

同時支援通知和應用内消息推送,api多語言,接口靈活)

3.騰訊推送(性能上還是可以的,因為項目是選擇用的極光,騰訊推送沒有經過實際大批量的驗證,以後用到了會進行補充)

4.百度雲推送(免費、不穩定,裝置綁定時常失效,背景界面不易調用)

5.個推(10000台線上連接配接數(約為DAV的70%)以上收費、偶爾會不穩定)

6.友盟推送(免費、相對穩定的到達率,背景界面醫用,可統計打開率(部分功能待優化)、可設定發送速度)

以上的廠商提供的推送服務,如果是中小型的項目免費的就可以,但是如果使用者量比較大,還是建議使用

收費的推送,相對來說收費開通的通道和資源比較多,減少了很多不必要的問題 

推送和通知NSNotification 的差別 

1.NSNotification是系統内部發出的通知,一般用于内部事件的監聽,或者狀态的改變等、是不可見的(建議不要濫用NSNotification,因為是在主線程中執行,使用不當會發生線程阻塞)

2.本地通知與遠端通知是可見的,主要使用者告知使用者或者發送一些App的内容更新,推送一些消息,讓App知道App内部發生了什麼事情。

iOS 常用的通知

1.本地推送通知:(Local Notification)

2.遠端推送通知:(Remote Notification)

iOS中通知顯示的效果

1.設定音效

2.設定橫幅

3.設定彈窗 

4.鎖屏下也可以呈現 

5.App圖示的數字 (注意:顯示彈窗或者橫幅效果是取決于使用者設定:通知中心-選擇應用-選擇下載下傳的通知模式)

通知的注意點:

1.App在前台運作的時候,通知不會展示出來

2.點選通知,預設會自動打開推送通知的App 

3.不管App是否打開,通知都可以如期發出 

1、本地推送通知:

一.關于通知注冊:

ios8之前:registerForRemoteNotificationTypes:

ios8之後:registerUserNotificationSettings

二.關于提醒角标

1.本地推送UILocalNotification的applicationIconBadgeNumber屬性隻會影響角标的顯示,不會影響通知欄的通知處理。

1)當applicationIconBadgeNumber>0時,角标會随applicationIconBadgeNumber而變化。

2)當applicationIconBadgeNumber=0時,角标維持推送前狀态不變。

3)當applicationIconBadgeNumber<0時,角标置0不顯示。

2.遠端推送的badge字段,隻會影響角标的顯示,不會影響通知欄的通知處理。

1)當badge>0時,角标會随badge而變化。

2)當badge=0時,角标維持不變。

3)當badge<0時,角标維持不變。

3.UIApplication的applicationIconBadgeNumber屬性既會影響角标的顯示,又會影響通知欄通知的處理。

1)當applicationIconBadgeNumber>0時,角标會随之變化,通知欄通知不變。

2)當applicationIconBadgeNumber=0時,角标變為0不顯示,通知欄通知清空。

3)當applicationIconBadgeNumber<0時,角标變為0不顯示,通知欄通知清空。

三.關于重複:

1. UILocalNotification.repeatInterval:repeatInterval的下限應該是NSCalendarUnitMinute,即每分鐘重複發送一次通知。如果設定為NSCalendarUnitSecond,那麼消息不會重複,每秒發送一次通知,iOS系統當然不會容許這樣的存在了。這裡比較不好的一點是NSCalendarUnit是個枚舉類型,該值不能自定義,例如你不能塞個10.0給它進而希望它每十秒重複一次。是以如果你想每20分鐘發送一次通知,一小時内發送3次,那麼隻能同時設定三個通知了。

2.若想設定複雜的重複通知,比如隻在每周的周一、周三重複,則隻能設定兩個通知,分别進行周重複提醒。

四.關于userInfo:userInfo可以攜帶使用者自定義的關于通知的資訊,通常可以用來作為不同通知的區分标志

五.關于接收通知:

1. 如果此時應用程式還在運作(無論是在前台還是在背景)則會調用-(void)application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification(如果是遠端通知則通過application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification)方法接收消息參數。參數中可以拿到notification對象,隻要讀取userInfo屬性區分不同的通知即可。

2. 如果應用程式已經完全退出此時會調用- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法:

1)通過點選通知欄通知進入:此時可以通路launchOptions中鍵為UIApplicationLaunchOptionsLocalNotificationKey的對象,這個對象就是發送的通知,由此對象再去通路userInfo。

2)通過點選圖示進入:可以通過[[UIApplication sharedApplication] scheduledLocalNotifications]擷取全部的排程通知,并通過userinfo進行區分

六:關于覆寫安裝:

如果我們的應用程式給系統發送的本地通知是周期性的,那麼即使把程式删了重裝,之前的本地通知在重裝時依然存在,沒有從系統中移除

通知的一些屬性:

// 枚舉值-發出通知的時間(有局限性)
@property(nonatomic) NSCalendarUnit repeatInterval;
// 自定義-發出通知的時間(可以自由設定時間)
@property(nonatomic,copy) NSCalendar *repeatCalendar;
// 區域-建立隻需要建立一個中心點與半徑就可以了
@property(nonatomic,copy) CLRegion *region
// 進入區域發出一個通知,設定yes,隻會發出一個通知,設定NO就會每次進入這個區域都發送
@property(nonatomic,assign) BOOL regionTriggersOnce NO
// 設定通知的内容
@property(nonatomic,copy) NSString *alertBody;      
 // 決定alertAction是否生效
@property(nonatomic) BOOL hasAction;
// 設定滑塊的文字
@property(nonatomic,copy) NSString *alertAction;    
// 設定點選通知的啟動圖檔(一般設定App啟動圖檔後,這裡可以随便寫)
@property(nonatomic,copy) NSString *alertLaunchImage;
// 設定alertTitle,就是通知内容上面的文字
@property(nonatomic,copy) NSString *alertTitle
 // 設定彈出的聲音
@property(nonatomic,copy) NSString *soundName;
 // 設定App的消息條數
@property(nonatomic) NSInteger applicationIconBadgeNumber;
 // 設定通知一些額外資料
 @property(nonatomic,copy) NSDictionary *userInfo;
           

如何發出本地通知:

// 1.建立本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];

    // 2.設定本地通知的内容
    // 2.1.設定通知發出的時間
    localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
    // 2.2.設定通知的内容
    localNote.alertBody = @"Good Morning?";
    // 2.3.設定滑塊的文字(鎖屏狀态下:滑動來“解鎖”)
    localNote.alertAction = @"解鎖";
    // 2.4.決定alertAction是否生效
    localNote.hasAction = NO;
    // 2.5.設定點選通知的啟動圖檔
    localNote.alertLaunchImage = @"$$$$";
    // 2.6.設定alertTitle
    localNote.alertTitle = @"您有一條新通知";
    // 2.7.設定有通知時的音效
    localNote.soundName = @"buyao.wav";
    // 2.8.設定應用程式圖示右上角的數字
    localNote.applicationIconBadgeNumber = 99;

    // 2.9.設定額外資訊
    localNote.userInfo = @{@"type" : @1};

    // 3.調用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
           

使用注意:

iOS7,不需要使用者授權就可發出通知,而iOS8以後,必須使用者授權才可以發出通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 設定應用程式的圖示右上角的數字
    [application setApplicationIconBadgeNumber:0];

    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
    }

    // 界面的跳轉(針對應用程式被殺死的狀态下的跳轉)
    // 殺死狀态下的,界面跳轉并不會執行下面的方法- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification,
    // 是以我們在寫本地通知的時候,要在這個與下面方法中寫,但要判斷,是通過哪種類型通知來打開的
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 跳轉代碼
        UILabel *redView = [[UILabel alloc] init];
        redView.frame = CGRectMake(0, 0, 200, 300);
        redView.numberOfLines = 0;
        redView.font = [UIFont systemFontOfSize:12.0];
        redView.backgroundColor = [UIColor redColor];
        redView.text = [NSString stringWithFormat:@"%@", launchOptions];
        [self.window.rootViewController.view addSubview:redView];
    }

    return YES;
}
           

監聽通知,如果使用者打開通知,可以讓使用者進入一些特定的界面

/*
 應用程式在進入前台,或者在前台的時候都會執行該方法
 */
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    // 必須要監聽--應用程式在背景的時候進行的跳轉
    if (application.applicationState == UIApplicationStateInactive) {
        NSLog(@"進行界面的跳轉");
      // 如果在上面的通知方法中設定了一些,可以在這裡列印額外資訊的内容,就做到監聽,也就可以根據額外資訊,做出相應的判斷
        NSLog(@"%@", notification.userInfo);

// 
        UIView *redView = [[UIView alloc] init];
        redView.frame = CGRectMake(0, 0, 100, 100);
        redView.backgroundColor = [UIColor redColor];
        [self.window.rootViewController.view addSubview:redView];
    }
}
           

2、遠端推送通知:

遠端推送服務APNS(Apple Push Notification Servers) 所有蘋果裝置在聯網的情況下都會與蘋果建立長連接配接 長連接配接: 1.隻要聯網就一直建立連接配接 2.長連接配接作用:1.時間校準2.系統更新3.查找我的iPhone等  長連接配接的好處 1.資料傳輸速度快  2.資料保持最新狀态  遠端推送的基本過程 1.用戶端app需要将使用者的UUID和app的bundleID發送給apps伺服器,進行注冊,apps伺服器将加密後的Device Token傳回給app  2.app獲得Device Token後,上傳到公司的伺服器  3.當需要推送通知時,公司的伺服器會将推送内容和Device Token一起發給apns伺服器  4.apns 再将推送的内容推送給用戶端 

用戶端要做的事情

1.注冊蘋果獲得Device Token  2.得到蘋果傳回的Device Token  3.發送Device Token給公司伺服器  4.監聽使用者通知的點選  調試遠端推送功能時,需要真機調試,模拟器接受不到遠端通知 真機測試相關内容 1.建立apeid(不帶*) 2.建立appid ssl 證書(獲得一個調試證書,一個釋出證書) 3.生成相應的描述檔案  4.安裝相關證書 

為什麼使用遠端推送? 解決傳統擷取資料的局限性,讓資料實時更新  使用場景 聊天功能(非及時聊天)、推送版本下載下傳、app活動、app内部新功能等 

iOS開發-本地通知與遠端通知
iOS開發-本地通知與遠端通知
iOS開發-本地通知與遠端通知
如何推送
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { //iOS8
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];
    } else { // iOS7
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert];
    }

// 根據遠端通知通過UIApplicationLaunchOptionsRemoteNotificationKey打開的情況來進行
    if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
        // 跳轉
        // 添加一個紅色的View
    }

    return YES;
}
           
// 擷取DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // 将DeviceToken傳給伺服器
    NSLog(@"%@", deviceToken.description);
}
           
// 正常接到遠端通知的時候會調用這個方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"%@", userInfo);
    // 正常打開推送後,
}
           
// 背景操作(根據收到推送,讓程式自己執行一些操作,不管使用者是否點選推送)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"---------");
    UIView *redV = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.frame = CGRectMake(100, 100, 100, 100);
    [self.window.rootViewController.view addSubview:redV];

    // 1.打開背景模式 2.告訴系統是否有新内容的更新 3.發送的通知有固定的格式("content-available":"1")
    // 2.告訴系統有新内容
    completionHandler(UIBackgroundFetchResultNewData);
}
           

1、打開背景模式 在Capabilities中找到Background Modes 設定YES 

2、告訴系統有新内容

completionHandler(UIBackgroundFetchResultNewData);

3、發送通知有固定格式

("content-available":"1")