推送通知
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);
}
三、第三方平臺的遠程推送通知
友盟、極光推送
推送的作用非常簡單,就是將我們服務器需要做的事情用激光推送服務器作爲替代。
極光推送給任何用戶不需要交錢,但是如果推送給特定的用戶則需要交錢。