APNs --Apple Push Notification Service

APNs 蘋果推送伺服器

Device 安裝帶有推送服務程式的iPhone手機
Provider 程式伺服器,把需要推送的資訊發給 APNs
DeviceToken 在Device第一次連接APNs時,由APNs生成的經過加密的連接認證資訊。在以後的連接中,無論時Provider到APNs還是APNs到Device 都需要 DeviceToken作為認證。
Payload 需要推送的消息的主體內容。alert-alert消息的消息體,按鍵標題等badge-顯示在程式icon右上角的數位,sound-聲音提示檔的檔案名,該聲音資源檔要在套裝程式中。

 

整體流程大體分為五個步驟:
1: Device --> 連接--> APNs 獲取 DeviceToken
2: Device-->連接-->Provider提供DeviceToken

0C075D55208459DBBEE7763584CDEFC0_332_217  






3: Provider偵測需要push的消息生成Notification資訊

F7D383889831987682C96EBA43114779_500_106  






4: Provider偵把要push的消息推送到APNs
5: APNs把該消息推送到手機

C08FE583861C6C1FDDF4288B3BCE5D2F_500_367  




介紹完APNS的概況,下面再瞭解一下具體的實現方法:

 

注:先申請APNS的證書,再進行以下操作。





1. 將app註冊notification裡面, 並從APNS上獲取測試機的deviceToken.




- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

 

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];

 

// other codes here.

 

return YES;

 

}




- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

 

NSLog(@"deviceToken: %@", deviceToken);

 

}




- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

 

NSLog(@"Error in registration. Error: %@", error);

 

}




- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

 

{




NSLog(@" 收到推送消息 : %@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);

 

if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=Null) {

 

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"推送通知"

 

message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]

 

delegate:self

 

cancelButtonTitle:@" 關閉"

 

otherButtonTitles:@" 更新狀態",nil];

 

[alert show];

 

[alert release];

 

}

 

}




啟動程式,將app註冊到通知項後,在console裡面找到列印的deviceToken:




deviceToken: <6974ac11 870e09fa 00e2238e 8cfafc7d 2052e342 182f5b57 fabca445 42b72e1b>






2. 生成app在服務端需要的許可證
1)進入Provisioning Portal, 下載Certificates在development下的證書。
2) 找到需要測試的app id,然後enable它在development下的Apple Push Notification service: Development Push SSL Certificate。需要輸入1)中的簽章憑證才可以生成一個aps_developer_identity.cer.
3) 按兩下aps_developer_identity.cer,會打開系統的key chain. 在My certificates下找到Apple Development Push Services。需要為certificate和它之下的private key各自export出一個.p12檔。(會出現設置密碼過程)
4)需要將上面的2個.p12檔轉成.pem格式:




openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12








openssl pkcs12 -nocerts -out key.pem -in key.p12





5)如果需要對 key不進行加密:





openssl rsa -in key.pem -out key.unencrypted.pem





6)然後就可以 合併兩個.pem檔, 這個ck.pem就是服務端需要的證書了。





cat cert.pem key.unencrypted.pem > ck.pem






3. 服務端push通知到ANPS. 在cocoachina找到了兩種方法:
1)php驅動。需要將ck.pem和php腳本放到server 上。全部的php代碼是:





<?php

 

$deviceToken = '6974ac11 870e09fa 00e2238e 8cfafc7d 2052e342 182f5b57 fabca445 42b72e1b';

 

$pass = '123456'; // Passphrase for the private key (ck.pem file)




// Get the parameters from HTTP get or from command line

 

$message = $_GET['message'] or $message = $argv[1] or $message = 'A test message from worldcup';

 

$badge = (int)$_GET['badge'] or $badge = (int)$argv[2];

 

$sound = $_GET['sound'] or $sound = $argv[3];




// Construct the notification payload

 

$body = array();

 

$body['aps'] = array('alert' => $message);

 

if ($badge)

 

$body['aps']['badge'] = $badge;

 

if ($sound)

 

$body['aps']['sound'] = $sound;




/* End of Configurable Items */

 

$ctx = stream_coNtext_create();

 

stream_coNtext_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');

 

// assume the private key passphase was removed.

 

stream_coNtext_set_option($ctx, 'ssl', 'passphrase', $pass);




// connect to apns

 

$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);

 

if (!$fp) {

 

print "Failed to connect $err $errstr\n";

 

return;

 

}

 

else {

 

print "Connection OK\n<br/>";

 

}




// send message

 

$payload = json_encode($body);

 

$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;

 

print "Sending message :" . $payload . "\n";

 

fwrite($fp, $msg);

 

fclose($fp);

 

?>





請 求一次 HTTP://127.0.0.1/apns/apns.php?message=A%20test%20message%20from%20localhost&badge=2&sound=received5.caf就 會向APNS進行一次推送。我的請求結果如下:




Connection OK

 

Sending message :{"aps":{"alert":"A test message from localhost","badge":2,"sound":"received5.caf"}}




參考文章

 

HTTP://blog.sina.com.cn/s/blog_46e3e7db0100roqt.html

 

HTTP://www.cocoachina.com/iphonedev/sdk/2010/0610/1668.html

(圖片來源--apple 開發文檔)
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()