推送通知跟NSNotification不同
1.NSNotification是抽象的,不可見的
2.推送通知是可見的
iOS中提供了2中推送通知
1.本地推送通知(Local Notification)
2.遠(yuǎn)程推送通知(Remote Notification)
推送的作用:可以讓不在前臺運行的app,告知客戶app內(nèi)部發(fā)生的事情.(QQ消息推送,微信消息推送等等)
推送通知的呈現(xiàn)效果:
1.在屏幕頂部顯示的一條橫幅
2.在屏幕中間彈出一個UIAlertView
3.在鎖屏界面顯示一塊橫幅
4.跟新app圖標(biāo)的數(shù)字
5.播放音效
本地通知
1.不需要服務(wù)器支持(無需聯(lián)網(wǎng))就能發(fā)出的推送通知
2.使用場景: 定時類任務(wù)(鬧鐘,簡單的游戲等等)
本地通知推送的實現(xiàn)很簡單:
1.創(chuàng)建本地推送通知對象
[[UILocalNotification alloc] init]
創(chuàng)建一個本地通知
2.設(shè)置本地通知的相關(guān)屬性
必須設(shè)置的屬性
2.1.推送通知的觸發(fā)時間(何時發(fā)出推送通知)
@property(nonatomic,copy) NSDate *fireDate
2.2.推送通知的具體內(nèi)容
@property(nonatomic,copy) NSString *alertBody
2.3.在鎖屏?xí)r顯示的動作標(biāo)題(完整測標(biāo)題:"滑動來" + alertAction)
@property(nonatomic,copy) NSString *alertAction
2.4.設(shè)置鎖屏界面alertAction是否有效
localNote.hasAction = YES;
2.5.app圖標(biāo)數(shù)字
@property(nonatomic,assign) NSInteger applicationIconBadgeNumber
2.6.調(diào)度本地推送通知(調(diào)度完畢后,推動通知會在特定時間fireDate發(fā)出)
[[UIApplication shareApplication] scheduleLocalNotification:ln]
可以進(jìn)行設(shè)置的設(shè)置
2.7.設(shè)置通知中心通知的標(biāo)題
localNote.alertTitle = @"222222222222";
2.8.設(shè)置音效(如果不設(shè)置就是系統(tǒng)默認(rèn)的音效, 設(shè)置的話會在mainBundle中查找)
localNote.soundName = @"buyao.wav";
2.9.每隔多久重復(fù)發(fā)一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval
2.10.點擊推送通知打開app時顯示的啟動圖片(mainBundle 中提取圖片)
@property(nonatomic,copy) NSSring *alertLaunchImage
2.11.附加的額外信息
@property(nonatomic,copy) NSDictionary *userInfo
2.12.時區(qū)
@property(nonatomic,copy) NSTimeZone *timeZone
(一般設(shè)置為[NSTimeZone defaultTimeZone],跟隨手機的時區(qū))
--代碼實現(xiàn)過程:
/*
@property(nonatomic,copy) NSDate *fireDate;
@property(nonatomic,copy) NSTimeZone *timeZone; 時區(qū)
@property(nonatomic) NSCalendarUnit repeatInterval; 重復(fù)間隔(枚舉)
@property(nonatomic,copy) NSCalendar *repeatCalendar; 重復(fù)日期(NSCalendar)
@property(nonatomic,copy) CLRegion *region 設(shè)置區(qū)域(設(shè)置當(dāng)進(jìn)入某一個區(qū)域時,發(fā)出一個通知)
@property(nonatomic,assign) BOOL regionTriggersOnce YES,只會在第一次進(jìn)入某一個區(qū)域時發(fā)出通知.NO,每次進(jìn)入該區(qū)域都會發(fā)通知
@property(nonatomic,copy) NSString *alertBody;
@property(nonatomic) BOOL hasAction; 是否隱藏鎖屏界面設(shè)置的alertAction
@property(nonatomic,copy) NSString *alertAction; 設(shè)置鎖屏界面一個文字
@property(nonatomic,copy) NSString *alertLaunchImage; 啟動圖片
@property(nonatomic,copy) NSString *alertTitle
@property(nonatomic,copy) NSString *soundName;
@property(nonatomic) NSInteger applicationIconBadgeNumber;
@property(nonatomic,copy) NSDictionary *userInfo; // 設(shè)置通知的額外的數(shù)據(jù)
*/
- (IBAction)addLocalNote:(id)sender {
// 1.創(chuàng)建一個本地通知
UILocalNotification *localNote = [[UILocalNotification alloc] init];
// 2.設(shè)置本地通知的一些屬性(通知發(fā)出的時間/通知的內(nèi)容)
// 2.1.設(shè)置通知發(fā)出的時間
localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0];
// 2.2.設(shè)置通知的內(nèi)容
localNote.alertBody = @"吃飯了嗎?";
// 2.3.設(shè)置鎖屏界面的文字
localNote.alertAction = @"查看具體的消息";
// 2.4.設(shè)置鎖屏界面alertAction是否有效
localNote.hasAction = YES;
// 2.5.設(shè)置通過點擊通知打開APP的時候的啟動圖片(無論字符串設(shè)置成什么內(nèi)容,都是顯示應(yīng)用程序的啟動圖片)
localNote.alertLaunchImage = @"111";
// 2.6.設(shè)置通知中心通知的標(biāo)題
localNote.alertTitle = @"222222222222";
// 2.7.設(shè)置音效
localNote.soundName = @"buyao.wav";
// 2.8.設(shè)置應(yīng)用程序圖標(biāo)右上角的數(shù)字
localNote.applicationIconBadgeNumber = 1;
// 2.9.設(shè)置通知之后的屬性
localNote.userInfo = @{@"name" : @"張三", @"toName" : @"李四"};
// 3.調(diào)度通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
當(dāng)消息被推送過來時,我們需要點擊推送消息,來完成一些特定的任務(wù).不如更新界面什么的(監(jiān)聽本地推送通知的點擊)
當(dāng)用戶點擊本地推送通知的時候,會自動打開app,這里有2種情況
1.app沒有關(guān)閉,只是一直隱藏在后臺
讓app進(jìn)入前臺,并會調(diào)用AppDelegate的下面的方法(并非重新啟動app)
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
----代碼實現(xiàn)
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// 在這里寫跳轉(zhuǎn)代碼
// 如果是應(yīng)用程序在前臺,依然會收到通知,但是收到通知之后不應(yīng)該跳轉(zhuǎn)
if (application.applicationState == UIApplicationStateActive) return;
if (application.applicationState == UIApplicationStateInactive) {
// 當(dāng)應(yīng)用在后臺收到本地通知時執(zhí)行的跳轉(zhuǎn)代碼
[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已經(jīng)被關(guān)閉(進(jìn)程被殺死)
啟動app,啟動完畢會調(diào)用AppDelegate的下面的方法
- (BOOL)application:(UIApplication *)application didFinishLaunchWithOptions:(NSDictionary *)launchOptions;
launchOptions參數(shù)通過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];
}
-----代碼實現(xiàn)相關(guān)操作
#define IS_iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/*
UIUserNotificationTypeNone = 0, 不發(fā)出通知
UIUserNotificationTypeBadge = 1 << 0, 改變應(yīng)用程序圖標(biāo)右上角的數(shù)字
UIUserNotificationTypeSound = 1 << 1, 播放音效
UIUserNotificationTypeAlert = 1 << 2, 是否運行顯示橫幅
*/
[application setApplicationIconBadgeNumber:0];
if (IS_iOS8) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}
// 如果是正常啟動應(yīng)用程序,那么launchOptions參數(shù)是null
// 如果是通過其它方式啟動應(yīng)用程序,那么launchOptions就值
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 當(dāng)被殺死狀態(tài)收到本地通知時執(zhí)行的跳轉(zhuǎn)代碼
// [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;
}
遠(yuǎn)程推送(Remote Notification)
1.從遠(yuǎn)程服務(wù)器推送給客戶端的通知(需要聯(lián)網(wǎng))
2.遠(yuǎn)程推送服務(wù), 蘋果起名為:APNS (Apple Push Notification Services)
解決問題:只要聯(lián)網(wǎng)了, 就能夠接收到服務(wù)器推送的遠(yuǎn)程通知
使用須知:
所有的蘋果設(shè)備,在聯(lián)網(wǎng)狀態(tài)下,都會與蘋果服務(wù)器建立長連接.
1.長連接:一直連接,客戶端與服務(wù)器
2.長連接作用:
1>事件校準(zhǔn)
2>系統(tǒng)升級
3>查找我的iPhone等....
3.長連接的好處
1>數(shù)據(jù)傳輸速度快
2>數(shù)據(jù)保持最新狀態(tài)
官方結(jié)實長連接的使用
1.獲得deviceToken
的過程
1>客戶端向蘋果服務(wù)APNS,發(fā)送設(shè)備的UDID和英語的Bundle Identifier.
2>經(jīng)蘋果服務(wù)器加密生成一個deviceToken
3>將當(dāng)前用戶的deviceToken(用戶標(biāo)識),發(fā)送給自己應(yīng)用的服務(wù)器
4>自己的服務(wù)器,將得到的deviceToken,進(jìn)行保存
2.利用deviceToken
進(jìn)行數(shù)據(jù)傳輸,推送通知
5>需要推送的時候,將消息和deviceToken一起發(fā)送給APNS,蘋果服務(wù)器,再通過deviceToken找到用戶,并將消息發(fā)給用戶
這里不再演示關(guān)于證書的配置, 簡單的只進(jìn)行說明步驟:
1> 創(chuàng)建明確的AppID,只有明確的AppID才能進(jìn)行一些特殊的操作
2>真機調(diào)試的APNS SSL證書
3>發(fā)布程序的APNS SSL證書
4>生成描述文件
[依次安裝證書, 再裝描述]
注冊遠(yuǎn)程推送通知:
1.客戶端如果想要接收APNs的遠(yuǎn)程推送通知,必須先進(jìn)行注冊(得到用戶授權(quán))
一般在APP啟動完畢后就馬上進(jìn)行注冊
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
// 1.注冊UserNotification,以獲取推送通知的權(quán)限
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
[application registerUserNotificationSettings:settings];
// 2.注冊遠(yuǎn)程推送
[application registerForRemoteNotifications];
} else {
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
return YES;
}
2.注冊成功后, 調(diào)用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沒有關(guān)閉,只是一直隱藏在后臺
讓app進(jìn)入前臺, 并調(diào)用下面的方法(app沒有重新啟動)
過期的方法:
// 當(dāng)接受到遠(yuǎn)程退職時會執(zhí)行該方法(當(dāng)進(jìn)入前臺或者應(yīng)用程序在前臺)
- (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];
}
蘋果系統(tǒng)建議使用下面的方法:
/*
1.開啟后臺模式
2.調(diào)用completionHandler,告訴系統(tǒng)你現(xiàn)在是否有新的數(shù)據(jù)更新
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已經(jīng)關(guān)閉,需要重新開啟,---基本實現(xiàn)方法和本地通知yi'zhi