IOS的推送實(shí)現(xiàn)由這樣幾步來完成:
創(chuàng)建Push SSL Certification
IOS客戶端注冊(cè)Push功能并獲得DeviceToken
使用Provider向APNS發(fā)送Push消息
IOS客戶端接收處理由APNS發(fā)來的消息
創(chuàng)建Push SSL Certification
登錄developer.apple.com,創(chuàng)建新的App ID,要求此ID的Bundle Identifier不包含通配符,否則不能啟用Push以及IAP功能。例如 com.soso.sosoimage。
在App IDs列表頁面,點(diǎn)擊剛創(chuàng)建的app id右面的Configure鏈接,進(jìn)入Configure App ID界面,選中"Enable for App Push Notification service"。點(diǎn)擊Development Push SSL Certificate一行的Configure按鈕,彈出"Apple Push Notification service SSL Certificate Assistant"對(duì)話框,依對(duì)話框操作,類似于創(chuàng)建開發(fā)或發(fā)布用的Certificate。
最終將Development Push SSL Certificate下載并安裝到本地Keychain Access。導(dǎo)出成p12文件,備用。導(dǎo)出時(shí)需要設(shè)置密碼,不得為空。
在developer.apple.com,創(chuàng)建一個(gè)新的Provisioning Profile,使用我們剛剛創(chuàng)建的支持Push功能的App ID。下載并安裝到本地。
IOS客戶端注冊(cè)Push功能并獲得DeviceToken
創(chuàng)建本地工程,info.plist中設(shè)置Bundle identifier為剛剛創(chuàng)建的Bundle Id。Com.soso.sosoimage。設(shè)定Code Signing Identity為剛剛創(chuàng)建的Provisioning Profile。
程序第一次執(zhí)行的時(shí)候,調(diào)用如下代碼.
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
三個(gè)參數(shù)分別代表消息(橫幅或提醒,由用戶Setting決定,程序不可更改)、數(shù)字標(biāo)記、聲音。
在AppDelegate.m中添加兩個(gè)方法.
//iPhone 從APNs服務(wù)器獲取deviceToken后回調(diào)此方法
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
NSLog(@"deviceToken:%@", dt);
}
//注冊(cè)push功能失敗 后 返回錯(cuò)誤信息,執(zhí)行相應(yīng)的處理
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
NSLog(@"Push Register Error:%@", err.description);
}
獲取DeviceToken后,將其傳給Provider。
使用Provider向APNS發(fā)送Push消息
Provider,將推送信息發(fā)送給APNS(蘋果推送服務(wù)器)的程序。有很多開源的實(shí)現(xiàn),我們使用javapns ( )。
首先,Provider要有目標(biāo)DeviceToken,這是發(fā)送目標(biāo),由客戶端傳給Provider之后存在某處。
安裝javapns,需要導(dǎo)入的jar為bcprov-jdk15-146.jar, log4j-1.2.15.jar, JavaPNS_2.3_Alpha_5.jar。
將前面導(dǎo)出的P12文件放在Provider的工程目錄下。
Provider向APNS發(fā)送消息可以參考javapns中NotificationTest.java。也可以參考如下例子。
(1)使客戶端圖標(biāo)顯示數(shù)字標(biāo)記
Push.badge(2, keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
其中,2為要顯示的數(shù)字;
String keystore = "PushCertificates.p12"; //P12文件的路徑;
String password = "sosoimage"; //P12文件的密碼;
false,指的是使用測(cè)試環(huán)境,使用正式產(chǎn)品環(huán)境應(yīng)傳入true.
"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67"為客戶端獲得并傳給Provider的DeviceToken,此參數(shù)還可以傳入String[]對(duì)象,以同時(shí)向多個(gè)客戶端Push消息。
(2)使客戶端顯示橫幅或提醒
Provider可以向客戶端Push一條Message,但客戶端有權(quán)限決定這條Message的顯示方式(無、橫幅、提醒)。
Push.alert("A Message", keystore, password, )false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
(3)混合方式
可以在一個(gè)Push消息里附帶多種信息,Message, 標(biāo)記,聲音,可以使用如下代碼.
PushNotificationPayload payload = PushNotificationPayload.complex();
payload.addAlert("A Message");
payload.addBadge(2);
payload.addSound("test.aiff");
Push.payload(payload, , keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
上面的代碼都有可能會(huì)有相應(yīng)的Exception拋出來,需要處理。更多的使用方式可以參考
IOS客戶端接收處理由APNS發(fā)來的消息
(1)當(dāng)程序未啟動(dòng),用戶接收到消息。需要在AppDelegate中的didFinishLaunchingWithOptions得到消息內(nèi)容。代碼如下,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
NSDictionary* payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (payload)
{
...
}
...
}
(2)當(dāng)程序在前臺(tái)運(yùn)行,接收到消息不會(huì)有消息提示(提示框或橫幅)。當(dāng)程序運(yùn)行在后臺(tái),接收到消息會(huì)有消息提示,點(diǎn)擊消息后進(jìn)入程序,AppDelegate的didReceiveRemoteNotification函數(shù)會(huì)被調(diào)用(需要自己重寫),消息做為此函數(shù)的參數(shù)傳入,代碼如下
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
{
...
}
(3)無論在哪個(gè)函數(shù)傳入,消息總是一個(gè)NSDictionary對(duì)象,處理方式可以參考如下代碼
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
{
NSLog(@"remote notification:description]);
NSString* alertStr = nil;
NSDictionary *apsInfo = [payload objectForKey:@"aps"];
NSObject *alert = [apsInfo objectForKey:@"alert"];
if ([alert isKindOfClass:[NSString class]])
{
alertStr = (NSString*)alert;
}
else if ([alert isKindOfClass:[NSDictionary class]])
{
NSDictionary* alertDict = (NSDictionary*)alert;
alertStr = [alertDict objectForKey:@"body"];
}
application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];
if ([application applicationState] == UIApplicationStateActive && alertStr != nil)
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
}
更多信息請(qǐng)查看IT技術(shù)專欄