iOS,推送通知

推送通知css

推送通知跟NSNotification有所區別: 
1> NSNotification是抽象的,不可見的 
2> 推送通知是可見的(能用肉眼看到)ios

iOS中提供了2種推送通知: 本地推送通知, 遠程推送通知 
1> 本地推送通知(Local Notification) 
2> 遠程推送通知(Remote Notification)數組

推送通知能夠不讓在前臺運行的app,告知app內部發生了什麼變化,好比:有新的內容,新消息等.服務器

推送通知的使用: 
發出推送通知時,若是當前程序正運行在前臺,那麼推送通知就不會被呈現出來 
點擊推送通知後,默認會自動打開發出推送通知的app 
無論app打開仍是關閉,推送通知都能如期發出網絡

推送通知有5種呈現效果: 
1. 在屏幕頂部顯示一塊橫幅(顯示具體內容) 
2. 在屏幕中間彈出一個UIAlertView(顯示具體內容,使用較少) 
3. 在鎖屏界面顯示一塊橫幅(鎖屏狀態下,顯示具體內容) 
4. 播放音效(提醒做用) 
5. 更新app圖標的數字(說明新內容的數量)app

推送通知分爲本地推送通知和遠程推送通知,下面一一介紹.ide

本地推送通知測試

本地推送通知不須要服務器的支持,不須要聯網就能夠發送通知.一般本地推送通知用於定時提醒用戶,好比清理垃圾,淘寶購物,記念日提醒等任務. 
在蘋果官方給出了本地推送通知的一些屬性,以及使用.fetch

屬性介紹:ui

@property(nonatomic,copy) NSDate *fireDate; // 設置本地推送的時間 @property(nonatomic,copy) NSTimeZone *timeZone; // 時區(通常設置爲[NSTimeZone defaultTimeZone] ,跟隨手機的時區) @property(nonatomic) NSCalendarUnit repeatInterval; // 沒隔多久重複發出一次 @property(nonatomic,copy) NSCalendar *repeatCalendar; // 設置日期 @property(nonatomic,copy) CLRegion *region NS_AVAILABLE_IOS(8_0); // 好比某一個區域的時候發出通知 @property(nonatomic,assign) BOOL regionTriggersOnce NS_AVAILABLE_IOS(8_0); // 進入區域是否重複 @property(nonatomic,copy) NSDictionary *userInfo; // 附加的額外信息 @property(nonatomic,copy) NSString *alertBody; // 消息的內容 @property(nonatomic) BOOL hasAction; // 是否顯示alertAction的文字(默認是YES) @property(nonatomic,copy) NSString *alertAction; // 設置鎖屏狀態下,顯示的一個文字 @property(nonatomic,copy) NSString *alertLaunchImage; // 啓動圖片 @property(nonatomic,copy) NSString *soundName; // UILocalNotificationDefaultSoundName @property(nonatomic) NSInteger applicationIconBadgeNumber; // 應用圖標右上角的提醒數字 @property(nonatomic,copy) NSArray *scheduledLocalNotifications; // 得到被調度(定製)的全部本地推送通知(已經發出且過時的推送通知就算調度結束,會自動從這個數組中移除) 

 

使用方法:

建立本地通知

UILocalNotification *localNoti = [[UILocalNotification alloc] init];

 

調度本地推送通知(調度完畢後,推送通知會在特意時間fireDate發出)

取消調度本地推送通知[[UIApplication sharedApplication] scheduleLocalNotification:localNoti];

- (void)cancelLocalNotification:(UILocalNotification *)notification; - (void)cancelAllLocalNotifications;

 

  • 當即發出本地推送通知
- (void)presentLocalNotificationNow:(UILocalNotification *)notification;

 

注意: 
iOS8.0之後在本地推送通知上新加了一些新功能,爲了用戶體驗,以及更加人性化,若是要使用本地通知,須要獲得用戶的許可. 
須要在AppDelegate中添加以下代碼

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /* UIUserNotificationTypeNone = 0, 沒有,沒有本地通知 UIUserNotificationTypeBadge = 1 << 0, 接受圖標右上角提醒數字 UIUserNotificationTypeSound = 1 << 1, 接受通知時候,能夠發出音效 UIUserNotificationTypeAlert = 1 << 2, 接受提醒(橫幅/彈窗) */ // iOS8須要添加請求用戶的受權 if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; } }

 

 

點擊本地推送通知 
當用戶點擊本地推送通知,會自動打開app,這裏有2種狀況

1> app並無關閉,一直隱藏在後臺(運行在後臺) 
讓app進入前臺,並會調用AppDelegate的下面方法(並不是從新啓動app)

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
  • 1
  • 1

2> app已經被關閉(進程已死) 
啓動app,啓動完畢會調用AppDelegate的下面方法

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

 

launchOptions參數經過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象

若要實現界面的跳轉,須要分清當前應用程序的所處狀態,進行判斷: 
1> 如果當前應用在後臺運行,接收到通知時,要想進行界面的跳轉,能夠在didReceiveLocalNotification:方法中實現跳轉界面的方法 
2> 如果當前的應用程序已經關閉,咱們在前面說到,當應用關閉,推送通知也會如期發送.但此時,是不會走didReceiveLocalNotification:方法的,那咱們只有didFinishLaunchingWithOptions:方法利用,launchOptions參數經過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象,實現跳轉的功能.

下面是演示代碼:

#import "ViewController.h"#import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /* UIUserNotificationTypeNone = 0, 沒有,沒有本地通知 UIUserNotificationTypeBadge = 1 << 0, 接受圖標右上角提醒數字 UIUserNotificationTypeSound = 1 << 1, 接受通知時候,能夠發出音效 UIUserNotificationTypeAlert = 1 << 2, 接受提醒(橫幅/彈窗) */ // iOS8須要添加請求用戶的受權 if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; } if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { // 跳轉界面 } return YES; } /** * 若是應用在後臺,經過點擊通知的時候打開應用會來到該代理方法 * 若是應用在前臺,接受到本地通知就會調用該方法 * * @param notification 經過哪個通知來這裏 */ - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { if (application.applicationState == UIApplicationStateActive) return; if (application.applicationState == UIApplicationStateInactive) { // 實現跳轉 } } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return YES; }



 @interface ViewController () // 點擊按鈕以後添加通知 - (IBAction)addLocalNote; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; } - (IBAction)addLocalNote { // 1.建立本地通知 UILocalNotification *localNote = [[UILocalNotification alloc] init]; // 設置什麼時間彈出 localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // 設置彈出的內容 localNote.alertBody = @"您有新消息"; // 設置鎖屏狀態下,顯示的一個文字 localNote.alertAction = @"快點打開"; // 是否顯示alertAction的文字(默認是YES) localNote.hasAction = YES; // 設置音效 localNote.soundName = UILocalNotificationDefaultSoundName; // 應用圖標右上角的提醒數字 localNote.applicationIconBadgeNumber = 1; // 設置UserInfo來傳遞信息 localNote.userInfo = @{@"alertBody" : localNote.alertBody, @"applicationIconBadgeNumber" : @(localNote.applicationIconBadgeNumber)}; // 2.調度通知 [[UIApplication sharedApplication] scheduleLocalNotification:localNote]; }

 

遠程推送通知

遠程推送通知:就是經過網絡從遠程服務器推送給客戶端的通知.

爲何須要遠程推送通知? 
傳統獲取數據的侷限性 
只要用戶關閉了app,就沒法跟app的服務器溝通,沒法從服務器上得到最新的數據內容

遠程推送通知能夠解決以上問題 
無論用戶打開仍是關閉app,只要聯網了,都能接收到服務器推送的遠程通知

遠程推送通知的使用 
全部的蘋果設備,在聯網狀態下,都會與蘋果的服務器創建長鏈接 
長鏈接: 只要聯網了,就一直創建鏈接

長鏈接的做用: 時間校準, 系統升級, 查找個人iPhone

長鏈接的好處 : 數據傳輸速度快 , 數據保持最新狀態

遠程推送功能機制

蘋果給iOS和Mac添加了消息推送的功能,使得咱們能夠經過後臺服務器給應用程序(APP)發送消息,無論APP是否正在使用,好比郵箱的來件提示功能。這項服務被稱爲Apple Push Notification service(APNs)。裏面一共涉及到四個角色:APP、設備、APNs和應用後臺服務器(Provider),其中APP、後臺服務器和APNs之間使用deviceToken惟一的標識一個用戶。 
這裏寫圖片描述

推送服務的工做流程:

APP向系統註冊推送服務。
設備從APNs請求deviceToken。
經過代理方法將deviceToken返回給APP。
APP將deviceToken發送給應用後臺服務器(Provider)。
應用後臺服務器保存deviceToken,而後在須要推送通知的時候,給APNs發送信息,使用deviceToken標識所要送達的客戶端。
APNs將後臺服務器發過來的數據推送到設備。
設備將消息分發給應用程序。

在使用推送功能的時候,須要在開發者中心建立支持Push Notification的證書,而且將證書和私鑰用於應用後臺服務器與APNs之間通訊。

我也寫了一個比較易懂的遠程推送流程圖! http://blog.csdn.net/ismilesky/article/details/48324723

遠程推送近年來,都是經過第三方進行實現,由於第三方推送的功能比較強大. 
推送平臺: 百度推送 , 極光推送, 騰訊信鴿推送, 個推 
遠程推送咱們這裏以極光推送(第三方)爲例,進行測試.

極光遠程推送的使用

如要使用極光第三方遠程推送,咱們須要集成iOS SDK,須要進行應用的配置,和環境配置.在開發者中心有 
developer.apple.com開發者帳號 , iOS真機(iPhone、iPad、iPod)等。

遠程推送應用配置過程:

  1. 建立支持遠程推送功能的App ID
  2. 申請開發者證書,並選中剛剛建立的App ID
  3. 下載CER文件,並導入鑰匙串管理
  4. 申請發佈證書,並選中剛剛建立的App ID
  5. 下載CER文件,並導入鑰匙串管理
  6. 檢查App ID,確認證書已經指定

這些相關配置極光推送已經給了很是詳細的文檔資料, iOS SDK集成指南 :http://docs.jpush.io/guideline/ios_guide/ , iOS SDK調試指南 :http://docs.jpush.io/client/ios_tutorials/#ios-sdk, 只須要按照流程進行就能夠.

實現代碼:

測試時,運行完應用程序,要發送通知,進行推送的測試,真機收到通知纔算成功. #define kDeviceVersion ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) #import "AppDelegate.h" #import "APService.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1 if (kDeviceVersion) { //能夠添加自定義categories [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound |UIUserNotificationTypeAlert) categories:nil]; } else { //categories 必須爲nil [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil]; } #else //categories 必須爲nil [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil]; #endif [APService setupWithOption:launchOptions]; return YES; } #pragma mark - 獲取device token (必須實現) // 當獲得蘋果的APNs服務器返回的DeviceToken就會被調用 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"%@",deviceToken); // Required [APService registerDeviceToken:deviceToken]; } #pragma mark - 獲取device token失敗 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"function == %s line == %d error == %@",__FUNCTION__,__LINE__,error); } // 接收到遠程通知,觸發方法和本地通知一致 (必須實現) - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Required [APService handleRemoteNotification:userInfo]; } #pragma mark - 使用後臺的遠程消息推送 (必須實現) /** 1> 在Capabilities中打開遠程推送通知 2> 實現該代理方法 遠程消息數據格式: {"aps" : {"content-available" : 1},"content-id" : 42} 執行completionHandler有兩個目的 1> 系統會估量App消耗的電量,並根據傳遞的UIBackgroundFetchResult 參數記錄新數據是否可用 2> 調用完成的處理代碼時,應用的界面縮略圖會自動更新 注意:接收到遠程通知到執行完網絡請求之間的時間不能超過30秒 if (userInfo) { int contentId = [userInfo[@"content-id"] intValue]; ViewController *vc = (ViewController *)application.keyWindow.rootViewController; [vc loadDataWithContentID:contentId completion:^(NSArray *dataList) { vc.dataList = dataList; NSLog(@"刷新數據結束"); completionHandler(UIBackgroundFetchResultNewData); }]; } else { completionHandler(UIBackgroundFetchResultNoData); } */ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // IOS 7 Support Required [APService handleRemoteNotification:userInfo]; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0]; // 判斷應用程序在前臺仍是後臺 if (application.applicationState == UIApplicationStateActive) { // 活躍狀態 // 實現方法 } else if (application.applicationState == UIApplicationStateInactive) { // 不活躍狀態 // 實現方法 } else { // application.applicationState == UIApplicationStateBackground // 後臺 // 實現方法 } /** 必須回調 */ completionHandler(UIBackgroundFetchResultNewData); }

這裏寫圖片描述

相關文章
相關標籤/搜索