標籤:
什麼是訊息推送
舉一個常見的例子,我們的手機上經常會有彈出一些資訊,例如QQ資訊、資訊等等,這就是常見的訊息推送。
例如:
訊息推送的類型:
- 在螢幕頂部顯示一塊橫幅(顯示具體內容)
- 在螢幕中間彈出一個UIAlertView(顯示具體內容)
- 在鎖定畫面顯示一塊橫幅(鎖屏狀態下,顯示具體內容)
- 更新app表徵圖的數字(說明新內容的數量)
- 播放音效(提醒作用)
這是我們常見的推送訊息的樣式,我們可以在手機上自訂接收的訊息如何展示。
在一些軟體中,如果使用者不小心關閉了我們的推送服務,我們也可以這樣提示使用者怎麼開啟允許接收推送服務(iOS8以後)。
注意:
訊息推送和平常的從伺服器擷取資料有什麼不同?
- 當我們從伺服器擷取資料的時候,我們會
主動向伺服器發送訊息,然後伺服器才會給我們發送我們需要的資訊;而訊息推送是當我們不在聊天狀態下,甚至是連QQ軟體都沒有開啟的情況下,伺服器主動向我們發送訊息,告訴我們一些資訊。
當然了,訊息推送和通知(NSNotification)可不一樣,雖然它們的使用類名看起來有點相似。
- NSNotification是抽象的,不可見的
- 訊息推送是可見(肉眼可見的)
本地推送
在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的步驟就可以很好的解釋遠程推送的過程了,而用戶端需要做的只有幾個步驟:
其餘的步驟由伺服器端實現:
4:自己的伺服器或者第三方推送伺服器將用戶端發送過來的使用者資訊儲存在自己的伺服器中
5:有人發送訊息的時候,從伺服器中(根據deviceToken)查詢要發給誰
6:查詢到要發送給某人以後,將資訊發送給蘋果伺服器
7:蘋果伺服器根據得到的deviceToken和資訊,查到要接受資訊的裝置和app,將資訊發送給使用者。
調試iOS的遠程推送功能, 必備條件:
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改成和上面配置的成相同名字。
如果還是不行,檢查這裡
將配置好的認證下載後安裝。
接下來就可以開始處理遠程推送的訊息了:
- 1、向蘋果註冊我們的裝置,並擷取到deviceToken
注意:
在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
- PushMeBaby是一款用來測試ANPs的開源Mac項目
- 它充當了伺服器的作用,用法非常簡單
- 它負責將內容提交給蘋果的APNs伺服器,蘋果的APNs伺服器再將內容推送給使用者的裝置
- PushMeBaby的首頁
https://github.com/stefanhafeneger/PushMeBaby
使用步驟:
填寫必要資訊
deviceToken:用於找到裝置的令牌
payload:推送的內容
- 將推送的調試認證改為名apns.cer,添加到PushMeBaby項目中
- command + R啟動程式,然後點擊Push
接下來就可以在裝置上接收到遠程推播通知
常用的第三方推送(極光推送)
什麼是JPush
一套遠程推送解決方案,支援android和iOS兩個平台
它能夠快捷地為iOS App增加推送功能,減少整合APNs需要的工作量、開發複雜度
更多的資訊,可以參考JPush官方網站:https://www.jpush.cn
整合iOS SDK的步驟可以參考
http://docs.jpush.cn/pages/viewpage.action?pageId=2621727
iOS-本地推送和遠程推送,常用的三方推送和常用的測試方法,推送實現和原理詳解(轉載自薛銀亮 [email protected])