iOS開發推送小結

iOS開發推送小結

本文主要介紹在iOS開發中使用Apple Push Notification Server的具體使用過程, 其實使用過程並不複雜, 主要就是證書製作過程比較麻煩, 然後就是後期的調試可能需要花點時間, 關於證書的製作一定要仔細, 不然有可能重頭來一遍.

推送過程簡介

(1)App啓動過程中,使用UIApplication::registerForRemoteNotificationTypes函數與蘋果的APNS服務器通信,發出註冊遠程推送的申請。若註冊成功,回調函數application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken 會被觸發,App可以得到deviceToken,該token就是一個與設備相關的字符串.

(2)App獲取到DeviceToken後,將DeviceToken發送給自己的服務端。

(3)服務端拿到DeviceToken以後,使用證書文件,向蘋果的APNS服務器發起一個SSL連接。連接成功之後,發送一段JSON串,該JSON串包含推送消息的類型及內容。

(4)蘋果的APNS服務器得到JSON串以後,向App發送通知消息,使得App的回調函數application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo被調用,App從userInfo中即可得到推送消息的內容。

證書生成過程

(1)certSigningRequest文件,該文件在MAC系統中生成,用於在Apple網站上申請推送證書文件。生成過程:打開應用程序中的“鑰匙串訪問”軟件,從菜單中選擇 “鑰匙串訪問”-》“證書助理”-》“從證書頒發機構請求證書”,郵箱和名稱隨便填寫,然後選擇保存到磁盤,就可以在本地生成一個CertificateSigningRequest.certSigningRequest文件。

(2)註冊一個支持push的app id,後面會用到。生成過程:進入developer.apple.com,選擇member center - Certificates, Identifiers & Profiles - Identifiers- App Ids,然後選擇註冊app id,設置appid名稱,同時,app id suffix一欄必須選擇explicit app id,然後設置bundle id,最後勾選 App Services中的 Push Notifications,這樣就可以註冊一個支持push的aphid。

(3) 推送證書cer文件,該文件在developer.apple.com中生成,用於生成服務端需要的文件。生成過程:進入developer.apple.com,選擇member center - Certificates, Identifiers & Profiles - Certificates,然後選擇創建certificate,類型分爲Development和Product。這裏以Development爲例,選擇Apple Push Notification service SSL (Sandbox) ,然後下一步,選擇之前生成的支持push的AppId,然後下一步,提交之前創建的CSR文件,再下一步就可以生成cer文件,然後保存到本地。

(4)生成服務端使用的證書文件。如果是使用網上的mac 版PushMeBaby工具,在mac機器上進行推送消息的發送,那麼有上面的cer文件就夠了。如果是使用PHP、java/c#開發自己的服務端,那麼還需要將上面的cer文件做一個轉換,生成pem文件或者p12文件。

服務器端pem文件生成過程

php服務器

首先雙擊前面保存的cer文件,此時會打開“鑰匙串訪問”軟件,裏面會出現一個Apple Development IOS push services證書,一個公用密鑰和一個專用祕鑰,祕鑰的名稱與證書助理中填寫的名稱一致。

選中證書,導出爲 apns-dev-cert.p12 文件

選中專有祕鑰,導出爲apns-dev-key.p12文件

通過終端命令將這些文件轉換爲PEM格式:

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

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

最後, 需要將兩個pem文件合併成一個apns-dev.pem文件,此文件在連接到APNS時需要使用:

cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

java服務器

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

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

openssl pkcs12 -export -in apns-dev-cert.pem -inkey apns-dev-key.pem -certfile CertificateSigningRequest.certSigningRequest -name “push” -out push.p12

客戶端開發

(1)下載前面建立的cer文件和provisioning文件,雙擊,導入到xcode中,在build setting中code signing一欄裏選擇這兩個文件的名稱,這樣就可以將支持push的app部署到真機中。

(2)處理推送消息客戶端對推送消息的處理分兩種情況:

一. 在App沒有運行的情況下,系統收到推送消息,用戶點擊推送消息,啓動App。此時,不會執行前面提到的 didReceiveRemoteNotification函數,而是在App的applicationDidFinishLaunching函數中處理推送,通過以下代碼可以獲取推送消息中的數據: NSDictionary *userInfo =[launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

二 . 當APP處於前臺時,系統收到推送消息,此時系統不會彈出消息提示,會直接觸發application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo函數,推送數據在userInfo字典中。

當App處於後臺時,如果系統收到推送消息,當用戶點擊推送消息時,會執行application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo函數,此時AppDelegate中函數執行的順序爲:applicationWillEnterForegroundapplication:didReceiveRemoteNotificationapplicationDidBecomeActiveI

調試

生成provisioning文件,用於真機調試

進入developer.apple.com,選擇member center - Certificates, Identifiers & Profiles - Provisioning Profiles,然後選擇創建Provisioning file,接着選擇iOS App Development ,下一步選擇AppId,選中之前建立的支持push的appid,接着下一步選擇支持push的certificate,下一步勾選需要支持的device id,最後一步設置provisioning文件的文件名,這樣provisioning文件就生成了。

調試工具

PushMeBaby工具

如果只是希望在mac電腦上測試一下消息的推送,可以使用PushMeBaby工具,使用起來比較簡單。該工具是開源的,可以從https://github.com/stefanhafeneger/PushMeBaby 下載,代碼的執行過程實際上就是設置一下SSL證書,然後連接APNS,接着發送JSON數據。由於要處理SSL邏輯,因此代碼稍微多點。在使用工具時,將工程資源中的cer文件替換成自己的cer文件,然後將代碼中的deviceToken替換成自己設備的deviceToken即可。

php腳本

由於php已經內置了ssl模塊,因此使用php連接APNS服務器來發送json的過程實際上是很簡單的,代碼如下:該文件可以放到服務器中通過瀏覽器來訪問,也可以通過命令行的方式來解釋執行,代碼爲:$ php -f Pusher.php

代碼如下:

<?php

// ??????????deviceToken???????????????
$deviceToken = 'dffcb9e133a763fc320c95300fa8732ec4168405792b54d58dcbd347687d1331';

// Put your private key's passphrase here:
$passphrase = 'e/UkZY4reul,';

// Put your alert message here:
$message = 'ticktick push test';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
//??????????
 //$fp = stream_socket_client(?ssl://gateway.push.apple.com:2195?, $err, $errstr, 60, //STREAM_CLIENT_CONNECT, $ctx);
//?????????????appstore??????
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'content-available' => 1
);

$body['pm'] = array(
'data' => '1434696786060',
'type' => 'needSync'
);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
?>

總結

轉載出處:http://www.jianshu.com/p/51c540b403f6

發佈了40 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章