舉一個常見的例子,咱們的手機上常常會有彈出一些信息,例如QQ信息、微信信息等等,這就是常見的消息推送。android
例如:ios
這是咱們常見的推送消息的樣式,咱們能夠在手機上自定義接收的消息如何展現。git
在一些軟件中,若是用戶不當心關閉了咱們的推送服務,咱們也能夠這樣提示用戶怎麼打開容許接收推送服務(iOS8之後)。github
注意:數組
發出推送通知時,若是當前程序正運行在前臺,那麼推送通知就不會被呈現出來服務器
點擊推送通知後,默認會自動打開發出推送通知的app微信
無論app打開仍是關閉,推送通知都能如期發出網絡
消息推送和日常的從服務器獲取數據有什麼不一樣?app
主動向服務器
發送消息,而後服務器纔會給咱們發送咱們須要的信息;而消息推送是當咱們不在聊天狀態下,甚至是連QQ軟件都沒有打開的狀況下,服務器主動向咱們
發送消息,告訴咱們一些信息。固然了,消息推送和通知(NSNotification)可不同,雖然它們的使用類名看起來有點類似。iphone
在iOS中,推送分爲本地推送和遠程推送,本地推送不須要網絡(不須要服務器的支持),常見的應用場景例如:
事件提醒類的軟件,到了咱們自定義的時間,就會彈出一些信息告訴咱們該幹什麼了。
記帳類軟件,會提醒咱們的一些花銷等等。
咱們先來學習一下本地推送
UILocalNotification *ln = [[UILocalNotification alloc] init];
//推送通知的觸發時間(什麼時候發出推送通知) @property(nonatomic,copy) NSDate *fireDate; //推送通知的具體內容 @property(nonatomic,copy) NSString *alertBody; //在鎖屏時顯示的動做標題(完整標題:「滑動來」 + alertAction) @property(nonatomic,copy) NSString *alertAction; //音效文件名 @property(nonatomic,copy) NSString *soundName; //app圖標數字 @property(nonatomic) NSInteger applicationIconBadgeNumber; //每隔多久重複發一次推送通知 @property(nonatomic) NSCalendarUnit repeatInterval; //點擊推送通知打開app時顯示的啓動圖片 @property(nonatomic,copy) NSString *alertLaunchImage; //附加的額外信息 @property(nonatomic,copy) NSDictionary *userInfo; //時區 @property(nonatomic,copy) NSTimeZone *timeZone; (通常設置爲[NSTimeZone defaultTimeZone] ,跟隨手機的時區) //調度本地推送通知(調度完畢後,推送通知會在特意時間fireDate發出) [[UIApplication sharedApplication] scheduleLocalNotification:ln]; //得到被調度(定製)的全部本地推送通知 @property(nonatomic,copy) NSArray *scheduledLocalNotifications; (已經發出且過時的推送通知就算調度結束,會自動從這個數組中移除) //取消調度本地推送通知 - (void)cancelLocalNotification:(UILocalNotification *)notification; - (void)cancelAllLocalNotifications; //當即發出本地推送通知 - (void)presentLocalNotificationNow:(UILocalNotification *)notification;
//當用戶點擊本地推送通知,會自動打開app,這裏有2種狀況 //app並無關閉,一直隱藏在後臺 //讓app進入前臺,並會調用AppDelegate的下面方法(並不是從新啓動app) - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification; //app已經被關閉(進程已死) //啓動app,啓動完畢會調用AppDelegate的下面方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; //launchOptions參數經過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象 //當點擊通知進入app時,launchOptions參數纔會有值,當正常啓動app時,launchOptions爲null
注意:
在iOS 8.0中,若是要使用本地通知,須要獲得用戶的許可
在didFinishLaunchingWithOptions方法中添加以下代碼:
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [application registerUserNotificationSettings:settings];
實例:
//在須要的地方註冊本地消息推送 // 1.建立本地通知 UILocalNotification *localNote = [[UILocalNotification alloc] init]; // 2.設置本地通知的信息 // 2.1.設置提示信息 localNote.alertBody = @"吃飯了嗎?"; // 2.2.設置通知彈出的時間 localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0]; // 2.3.設置滑塊顯示的文字 localNote.alertAction = @"快點"; // 2.4.是否讓上面的文字生效 localNote.hasAction = NO; // 2.5.設置通知中心的標題 localNote.alertTitle = @"你大哥"; // 2.6.設置通知的聲音 localNote.soundName = @"buyao.wav"; // 2.7.設置應用程序圖標右上角的數字 localNote.applicationIconBadgeNumber = 10; // 3.調度通知 //調度前要先把原來的通知取消 UIApplication *app = [UIApplication sharedApplication]; [app cancelAllLocalNotifications]; [app scheduleLocalNotification:localNote];
在appdelegate類中實現相應的跳轉方法
#import "AppDelegate.h" #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]; } return YES; } //程序沒有關閉時,點擊通知進入app纔會調用,若是將程序徹底退出,點擊通知進入app時只會調用上面的方法,不會調用這個方法 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { // 在這裏寫跳轉代碼 // 若是是應用程序在前臺,依然會收到通知,可是收到通知以後不該該跳轉 if (application.applicationState == UIApplicationStateActive) return; if (application.applicationState == UIApplicationStateInactive) { // 當應用在後臺收到本地通知時執行的跳轉代碼 [self jumpToSession]; } } - (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]; } @end
先介紹一下iOS中遠程推送的原理:
咱們先要明確一點,全部的iOS設備收到的遠程推送消息都是經過蘋果的服務器發出來的。咱們本身公司的服務器或者第三方的推送服務器都是將要發送給咱們的推送消息先推給蘋果的服務器,而後再由蘋果的服務器發送給咱們。
以下圖:
因此,咱們的蘋果設備在聯網的狀況下,都會默認和蘋果的服務器保持一個長鏈接(這裏不解釋長鏈接的概念,你能夠理解成是有一條線一直在二者之間聯繫着,爲了保持服務器不斷開和咱們設備的聯繫,咱們的設備默認每隔一段時間會向服務器發送心跳包(一個很小的文件),來告訴蘋果服務器不要和咱們的設備斷開鏈接)。
下面詳細解釋一下iOS中的遠程推送原理
上圖中1-8的步驟就能夠很好的解釋遠程推送的過程了,而客戶端須要作的只有幾個步驟:
1:發送設備的UDID和
應用的Bundle Identifier
給APNs服務器
2:經蘋果加密生成一個
deviceToken
3:發送當前用戶的deviceToken
和用戶的標誌(好比id或者qq)到本身公司的服務器或者第三方推送服務器
4:監聽通知的點擊事件
其他的步驟由服務器端實現:
4:本身的服務器或者第三方推送服務器將客戶端發送過來的用戶信息保存在本身的服務器中
5:有人發送消息的時候,從服務器中(根據deviceToken)查詢要發給誰
6:查詢到要發送給某人之後,將信息發送給蘋果服務器
7:蘋果服務器根據獲得的deviceToken和信息,查到要接受信息的設備和app,將信息發送給用戶。
1.真機
2.調試推送須要的證書文件
1> aps_development.cer : 某臺電腦就能調試某個app的推送服務
2> iphone5_qq.mobileprovision : 某臺電腦就能利用某臺設備調試某個程序
三.發佈具備推送服務的app,須要的證書文件
1> aps_production.cer : 若是發佈的程序中包含了推送服務,就必須安裝這個證書
2> qq.mobileprovision : 某臺電腦就能發佈某個程序
下面就開始真正的使用一下遠程推送功能吧。
證書配置01 – 建立App ID
配置明確的App ID
大概步驟以下:
先選擇明確的App ID
配置遠程推送的調試證書
配置遠程推送的發佈證書(使用第二種方法配置)
新建項目,將Bundle ID改爲和上面配置的成相同名字。
若是仍是不行,檢查這裏
將配置好的證書下載後安裝。
接下來就能夠開始處理遠程推送的消息了:
注意:
在iOS7和iOS8中的註冊方法不同
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 請求獲取DeviceToken if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { // 1.獲取發送通知的權限 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:settings]; // 2.註冊遠程通知 [application registerForRemoteNotifications]; } else { [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound]; } return YES; } //獲取到deviceToken - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"%@", deviceToken); }
這裏有兩個方法,注意二者的區別,更具須要調用
//這個方法能夠處理當用戶點擊消息進入前臺作一些操做 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"%@", userInfo); }
//這個方法能夠實如今用戶手機收到消息就能夠在後臺進行一些操做,例如更新UI //不過,這個方法要先設置後臺模式,方法以下: /* 1.開啓後臺模式 2.調用completionHandler,告訴系統你如今是否有新的數據更新 3.userInfo添加一個字段:"content-available" : "1" : 只要添加了該字段,接受到通知都會在後臺運行 */ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { UIView *redView = [[UIView alloc] init]; redView.frame = CGRectMake(100, 100, 100, 100); redView.backgroundColor = [UIColor redColor]; [self.window.rootViewController.view addSubview:redView]; completionHandler(UIBackgroundFetchResultFailed); }
添加後臺模式方法:
下面介紹一種測試遠程通知的工具PushMeBaby
使用步驟:
填寫必要信息
deviceToken:用於找到設備的令牌
payload:推送的內容
什麼是JPush
一套遠程推送解決方案,支持android和iOS兩個平臺
它可以快捷地爲iOS App增長推送功能,減小集成APNs須要的工做量、開發複雜度
更多的信息,能夠參考JPush官方網站:https://www.jpush.cn
集成iOS SDK的步驟能夠參考 http://docs.jpush.cn/pages/viewpage.action?pageId=2621727