iOS網路推播通知

來源:互聯網
上載者:User

iOS網路推播通知

推播通知是由應用服務提供者發起的,通過蘋果的APNs(Apple Push Notification Server)發送到應用用戶端。

推播通知的過程可以分為以下幾步:

應用服務提供者從伺服器端把要發送的訊息和裝置令牌(device token)發送給蘋果的訊息推送伺服器APNs。
APNs根據裝置令牌在登入的裝置(iPhone、iPad、iTouch、mac等)尋找對應的裝置,將訊息發送給相應的裝置。
用戶端裝置接將接收到的訊息傳遞給相應的應用程式,應用程式根據使用者佈建彈出通知訊息。

1.應用程式註冊APNs推送訊息

說明:

a.只有註冊過的應用才有可能接收到訊息,程式中通常通過UIApplication的registerUserNotificationSettings:方法註冊,iOS8中通知註冊的方法發生了改變,如果是iOS7及之前版本的iOS請參考其他代碼。

b.註冊之前有兩個前提條件必須準備好:開發設定檔(provisioning profile,也就是.mobileprovision尾碼的檔案)的App ID不能使用通配ID必須使用指定APP ID並且組建組態檔案中選擇Push Notifications服務,一般的開發設定檔無法完成註冊;應用程式的Bundle Identifier必須和組建組態檔案使用的APP ID完全一致。

2.iOS從APNs接收device token,在應用程式擷取device token

說明:

a.在UIApplication的-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken代理方法中擷取令牌,此方法發生在註冊之後。

b.如果無法正確獲得device token可以在UIApplication的-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error代理方法中查看詳細錯誤資訊,此方法發生在擷取device token失敗之後。

c.必須真機調試,模擬器無法擷取device token。

3.iOS應用將device token發送給應用程式供應商,告訴伺服器端當前裝置允許接收訊息

說明:

a.device token的產生演算法只有Apple掌握,為了確保演算法發生變化後仍然能夠正常接收伺服器端發送的通知,每次應用程式啟動都重新獲得device token(注意:device token的擷取不會造成效能問題,蘋果官方已經做過最佳化)。

b.通常可以建立一個網路連接發送給應用程式供應商的伺服器端, 在這個過程中最好將上一次獲得的device token儲存起來,避免重複發送,一旦發現device token發生了變化最好將原有的device token一塊發送給伺服器端,伺服器端刪除原有令牌儲存新令牌避免伺服器端發送無效訊息。

4.應用程式供應商在伺服器端根據前面發送過來的device token組織資訊發送給APNs

說明:

a.發送時指定device token和訊息內容,並且完全按照蘋果官方的訊息格式組織訊息內容,通常情況下可以藉助其他第三方訊息推送架構來完成。

5.APNs根據訊息中的device token尋找登入的裝置推送訊息

說明:

a.正常情況下可以根據device token將訊息成功推送到用戶端裝置中,但是也不排除使用者卸載程式的情況,此時推送訊息失敗,APNs會將這個錯誤訊息通知伺服器端以避免資源浪費(伺服器端此時可以根據錯誤刪除已經儲存的device token,下次不再發送)。

#import "AppDelegate.h"
#import "KCMainViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
#pragma mark - 應用程式代理程式方法
#pragma mark 應用程式啟動之後
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

_window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];

_window.backgroundColor =[UIColor colorWithRed:249/255.0 green:249/255.0 blue:249/255.0 alpha:1];

//設定全域導航條風格和顏色
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1]];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

KCMainViewController *mainController=[[KCMainViewController alloc]init];
_window.rootViewController=mainController;

[_window makeKeyAndVisible];

//註冊推播通知(注意iOS8註冊方法發生了變化)
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
[application registerForRemoteNotifications];

return YES;
}
#pragma mark 註冊推播通知之後
//在此接收裝置令牌
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
[self addDeviceToken:deviceToken];
NSLog(@"device token:%@",deviceToken);
}
#pragma mark 擷取device token失敗後
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"didFailToRegisterForRemoteNotificationsWithError:%@",error.localizedDescription);
[self addDeviceToken:nil];
}
#pragma mark 接收到推播通知之後
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(@"receiveRemoteNotification,userInfo is %@",userInfo);
}
#pragma mark - 私人方法
/**
* 添加裝置令牌到伺服器端
*
* @param deviceToken 裝置令牌
*/
-(void)addDeviceToken:(NSData *)deviceToken{
NSString *key=@"DeviceToken";
NSData *oldToken= [[NSUserDefaults standardUserDefaults]objectForKey:key];
//如果喜好設定中的已存放裝置令牌和新擷取的令牌不同則儲存新令牌並且發送給伺服器端
if (![oldToken isEqualToData:deviceToken]) {
[[NSUserDefaults standardUserDefaults] setObject:deviceToken forKey:key];
[self sendDeviceTokenWidthOldDeviceToken:oldToken newDeviceToken:deviceToken];
}
}
-(void)sendDeviceTokenWidthOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken{
//注意一定確保真機可以正常訪問下面的地址
NSString *urlStr=@"http://192.168.1.101/RegisterDeviceToken.aspx";
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlStr];
NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0];
[requestM setHTTPMethod:@"POST"];
NSString *bodyStr=[NSString stringWithFormat:@"oldToken=%@&newToken=%@",oldToken,newToken];
NSData *body=[bodyStr dataUsingEncoding:NSUTF8StringEncoding];
[requestM setHTTPBody:body];
NSURLSession *session=[NSURLSession sharedSession];
NSURLSessionDataTask *dataTask= [session dataTaskWithRequest:requestM completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Send failure,error is :%@",error.localizedDescription);
}else{
NSLog(@"Send Success!");
}

}];
[dataTask resume];
}
@end

認證

iOS常用的認證包括開發認證和發布認證,無論是真機調試還是最終發布應用到App Store這兩個認證都是必須的,它是iOS開發的基本認證。

a.開發認證:開發認證又分為普通開發認證和推送認證,如果僅僅是一般的應用則前者即可滿足,但是如果開發推送應用則必須使用推送認證。

b.發布認證:發布認證又可以分為普通發布認證、推送認證、Pass Type ID認證、網站發布認證、VoIP服務憑證、蘋果支付認證。同樣的,對於需要使用特殊服務的應用則必須選擇對應的認證。

應用標識

App ID,應用程式的唯一標識,對應iOS應用的Bundle Identifier,App ID在蘋果開發人員中心中分為通配應用ID和明確的應用ID,前者一般用於普通應用開發,一個ID可以適用於多個不同標識的應用;但是對於使用訊息推送、Passbook、網站發布、iCloud等服務的應用必須配置明確的應用ID。

裝置標識

UDID,用於標識每一台硬體裝置的標示符。注意它不是device token,device token是根據UDID使用一個只有Apple自己才知道的演算法產生的一組標示符。

配置簡介

Provisioning Profiles,平時又稱為PP檔案。將UDID、App ID、開發認證打包在一起的設定檔,同樣分為開發和發布兩類設定檔。

秘鑰

在申請開發認證時必須要首先提交一個秘鑰請求檔案,對於產生秘鑰請求檔案的mac,如果要做開發則只需要下載認證和配置簡介即可開發。但是如果要想在其他機器上做開發則必須將認證中的秘鑰匯出(匯出之後是一個.p12檔案),然後匯入其他機器。同時對於類似於推送伺服器端應用如果要給APNs發送訊息,同樣需要使用.p12秘鑰檔案,並且這個秘鑰檔案需要是推送認證匯出的對應秘鑰。

補充--通知中樞

對於很多初學者往往會把iOS中的本地通知、推播通知和iOS通知中樞的概念弄混。其實二者之間並沒有任何關係,事實上它們都不屬於一個架構,前者屬於UIKit架構,後者屬於Foundation架構。

通知中樞實際上是iOS程式內部之間的一種訊息廣播機制,主要為瞭解決應用程式內部不同對象之間解耦而設計。它是基於觀察者模式設計的,不能跨應用程式進程通訊,當通知中樞接收到訊息之後會根據內部的訊息轉寄表,將訊息發送給訂閱者。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: