推送通知跟NSNotification不同
1.NSNotification是抽象的,不可見的
2.推送通知是可見的
iOS中提供了2中推送通知
1.本地推送通知(Local Notification)
2.遠程推送通知(Remote Notification)
推送的作用:可以讓不在前台運行的app,告知客戶app內部發生的事情.(QQ消息推送,微信消息推送等等)
推送通知的呈現效果:
1.在屏幕頂部顯示的一條橫幅
2.在屏幕中間彈出一個UIAlertView
3.在鎖屏界面顯示一塊橫幅
4.跟新app圖標的數字
5.播放音效
本地通知
1.不需要服務器支持(無需聯網)就能發出的推送通知
2.使用場景: 定時類任務(鬧鍾,簡單的游戲等等)
本地通知推送的實現很簡單:
1.創建本地推送通知對象
[[UILocalNotification alloc] init]
創建一個本地通知
2.設置本地通知的相關屬性
必須設置的屬性
2.1.推送通知的觸發時間(何時發出推送通知)
@property(nonatomic,copy) NSDate *fireDate
2.2.推送通知的具體內容
@property(nonatomic,copy) NSString *alertBody
2.3.在鎖屏時顯示的動作標題(完整測標題:"滑動來" + alertAction)
@property(nonatomic,copy) NSString *alertAction
2.4.設置鎖屏界面alertAction是否有效
localNote.hasAction = YES;
2.5.app圖標數字
@property(nonatomic,assign) NSInteger applicationIconBadgeNumber
2.6.調度本地推送通知(調度完畢后,推動通知會在特定時間fireDate發出)
[[UIApplication shareApplication] scheduleLocalNotification:ln]
可以進行設置的設置
2.7.設置通知中心通知的標題
localNote.alertTitle = @"222222222222";
2.8.設置音效(如果不設置就是系統默認的音效, 設置的話會在mainBundle中查找)
localNote.soundName = @"buyao.wav";
2.9.每隔多久重復發一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval
2.10.點擊推送通知打開app時顯示的啟動圖片(mainBundle 中提取圖片)
@property(nonatomic,copy) NSSring *alertLaunchImage
2.11.附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo
2.12.時區
@property(nonatomic,copy) NSTimeZone *timeZone
(一般設置為[NSTimeZone defaultTimeZone],跟隨手機的時區)
--代碼實現過程:

/* @property(nonatomic,copy) NSDate *fireDate; @property(nonatomic,copy) NSTimeZone *timeZone; 時區 @property(nonatomic) NSCalendarUnit repeatInterval; 重復間隔(枚舉) @property(nonatomic,copy) NSCalendar *repeatCalendar; 重復日期(NSCalendar) @property(nonatomic,copy) CLRegion *region 設置區域(設置當進入某一個區域時,發出一個通知) @property(nonatomic,assign) BOOL regionTriggersOnce YES,只會在第一次進入某一個區域時發出通知.NO,每次進入該區域都會發通知 @property(nonatomic,copy) NSString *alertBody; @property(nonatomic) BOOL hasAction; 是否隱藏鎖屏界面設置的alertAction @property(nonatomic,copy) NSString *alertAction; 設置鎖屏界面一個文字 @property(nonatomic,copy) NSString *alertLaunchImage; 啟動圖片 @property(nonatomic,copy) NSString *alertTitle @property(nonatomic,copy) NSString *soundName; @property(nonatomic) NSInteger applicationIconBadgeNumber; @property(nonatomic,copy) NSDictionary *userInfo; // 設置通知的額外的數據 */ - (IBAction)addLocalNote:(id)sender { // 1.創建一個本地通知 UILocalNotification *localNote = [[UILocalNotification alloc] init]; // 2.設置本地通知的一些屬性(通知發出的時間/通知的內容) // 2.1.設置通知發出的時間 localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0]; // 2.2.設置通知的內容 localNote.alertBody = @"吃飯了嗎?"; // 2.3.設置鎖屏界面的文字 localNote.alertAction = @"查看具體的消息"; // 2.4.設置鎖屏界面alertAction是否有效 localNote.hasAction = YES; // 2.5.設置通過點擊通知打開APP的時候的啟動圖片(無論字符串設置成什么內容,都是顯示應用程序的啟動圖片) localNote.alertLaunchImage = @"111"; // 2.6.設置通知中心通知的標題 localNote.alertTitle = @"222222222222"; // 2.7.設置音效 localNote.soundName = @"buyao.wav"; // 2.8.設置應用程序圖標右上角的數字 localNote.applicationIconBadgeNumber = 1; // 2.9.設置通知之后的屬性 localNote.userInfo = @{@"name" : @"張三", @"toName" : @"李四"}; // 3.調度通知 [[UIApplication sharedApplication] scheduleLocalNotification:localNote]; }
當消息被推送過來時,我們需要點擊推送消息,來完成一些特定的任務.不如更新界面什么的(監聽本地推送通知的點擊)
當用戶點擊本地推送通知的時候,會自動打開app,這里有2種情況
1.app沒有關閉,只是一直隱藏在后台
讓app進入前台,並會調用AppDelegate的下面的方法(並非重新啟動app)

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
----代碼實現
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { // 在這里寫跳轉代碼 // 如果是應用程序在前台,依然會收到通知,但是收到通知之后不應該跳轉 if (application.applicationState == UIApplicationStateActive) return; if (application.applicationState == UIApplicationStateInactive) { // 當應用在后台收到本地通知時執行的跳轉代碼 [self jumpToSession]; } NSLog(@"%@", notification); } - (void)jumpToSession { UILabel *redView = [[UILabel alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.frame = CGRectMake(0, 100, 300, 400); redView.numberOfLines = 0; // redView.text = [NSString stringWithFormat:@"%@", launchOptions]; [self.window.rootViewController.view addSubview:redView]; }
2.app已經被關閉(進程被殺死)

啟動app,啟動完畢會調用AppDelegate的下面的方法
- (BOOL)application:(UIApplication *)application didFinishLaunchWithOptions:(NSDictionary *)launchOptions;
launchOptions參數通過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象
需要特別注意的是:
在iOS8.0
以后本地通知有了一些變化,如果要使用本地通知,需要得到用戶的許可.
在
didFinishLaunchWithOptions
方法中添加如下代碼:
#define IS_iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) if (IS_iOS8) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; }
-----代碼實現相關操作
#define IS_iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /* UIUserNotificationTypeNone = 0, 不發出通知 UIUserNotificationTypeBadge = 1 << 0, 改變應用程序圖標右上角的數字 UIUserNotificationTypeSound = 1 << 1, 播放音效 UIUserNotificationTypeAlert = 1 << 2, 是否運行顯示橫幅 */ [application setApplicationIconBadgeNumber:0]; if (IS_iOS8) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; } // 如果是正常啟動應用程序,那么launchOptions參數是null // 如果是通過其它方式啟動應用程序,那么launchOptions就值 if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { // 當被殺死狀態收到本地通知時執行的跳轉代碼 // [self jumpToSession]; UILabel *redView = [[UILabel alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.frame = CGRectMake(0, 100, 300, 400); redView.numberOfLines = 0; redView.text = [NSString stringWithFormat:@"%@", launchOptions]; [self.window.rootViewController.view addSubview:redView]; } return YES; }
遠程推送(Remote Notification)
1.從遠程服務器推送給客戶端的通知(需要聯網)
2.遠程推送服務, 蘋果起名為:APNS (Apple Push Notification Services)
解決問題:只要聯網了, 就能夠接收到服務器推送的遠程通知
使用須知:
所有的蘋果設備,在聯網狀態下,都會與蘋果服務器建立長連接.
1.長連接:一直連接,客戶端與服務器
2.長連接作用:
1>事件校准
2>系統升級
3>查找我的iPhone等....
3.長連接的好處
1>數據傳輸速度快
2>數據保持最新狀態
官方結實長連接的使用
1.獲得deviceToken
的過程


1>客戶端向蘋果服務APNS,發送設備的UDID和英語的Bundle Identifier.
2>經蘋果服務器加密生成一個deviceToken
3>將當前用戶的deviceToken(用戶標識),發送給自己應用的服務器
4>自己的服務器,將得到的deviceToken,進行保存
2.利用deviceToken
進行數據傳輸,推送通知

5>需要推送的時候,將消息和deviceToken一起發送給APNS,蘋果服務器,再通過deviceToken找到用戶,並將消息發給用戶

這里不再演示關於證書的配置, 簡單的只進行說明步驟:
1> 創建明確的AppID,只有明確的AppID才能進行一些特殊的操作
2>真機調試的APNS SSL證書
3>發布程序的APNS SSL證書
4>生成描述文件
[依次安裝證書, 再裝描述]
注冊遠程推送通知:
1.客戶端如果想要接收APNs的遠程推送通知,必須先進行注冊(得到用戶授權)
一般在APP啟動完畢后就馬上進行注冊
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { // 1.注冊UserNotification,以獲取推送通知的權限 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil]; [application registerUserNotificationSettings:settings]; // 2.注冊遠程推送 [application registerForRemoteNotifications]; } else { [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound]; } return YES; }
2.注冊成功后, 調用AppDelegate的方法,獲取到用戶的deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // <32e7cf5f 8af9a8d4 2a3aaa76 7f3e9f8e 1f7ea8ff 39f50a2a e383528d 7ee9a4ea> // <32e7cf5f 8af9a8d4 2a3aaa76 7f3e9f8e 1f7ea8ff 39f50a2a e383528d 7ee9a4ea> NSLog(@"%@", deviceToken.description); }
3.點擊推送通知,和本地一樣有兩種狀況.
1> app沒有關閉,只是一直隱藏在后台
讓app進入前台, 並調用下面的方法(app沒有重新啟動)
過期的方法:
// 當接受到遠程退職時會執行該方法(當進入前台或者應用程序在前台) - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"%@", userInfo); UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.frame = CGRectMake(100, 100, 100, 100); [self.window.rootViewController.view addSubview:redView]; }
蘋果系統建議使用下面的方法:
/* 1.開啟后台模式 2.調用completionHandler,告訴系統你現在是否有新的數據更新 3.userInfo添加一個字段:"content-available" : "1" : 只要添加了該字段,接受到通知都會在后台運行 */ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSLog(@"%@", userInfo); UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.frame = CGRectMake(100, 100, 100, 100); [self.window.rootViewController.view addSubview:redView]; completionHandler(UIBackgroundFetchResultNewData); }
2>app已經關閉,需要重新開啟,---基本實現方法和本地通知yi'zhi
作者:Little_Dragon
鏈接:https://www.jianshu.com/p/e347f999ed95
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。