APNS遠程推送證書的申請和製做——詳細解析

在ios中,通知有兩種(提醒轟炸的來源):php

     第一種是本地通知(UILocalNotification,這一種不須要申請推送證書,也不須要向程序註冊,直接使用,這一種不是本文討論的範圍。linux

     第二種是APNS遠程推送——遠程通知(UIRemoteNotification),這個不只須要向程序註冊,也須要在開發者帳號裏申請推送證書,下面來介紹一下如何註冊和申請證書。ios

1、遠程推送的原理

先看下面一幅圖(圖片來源於無線互聯):
程序員


能夠看出,遠程推送的過程分爲6步,下面爲你們簡單講解一下:json

     第一步是在程序上註冊遠程通知,這是通知的前提程序員的工做),註冊好後,當用戶下載完咱們的應用並打開時,app會彈出一個alertView,問是否容許該應用像你發送通知,以下圖:服務器


     當用戶選擇「好」以後,ios 這個操做系統將會告訴APNS這個服務器,這樣一來,當程序運行時,apns就會給程序發送那一臺設備的 device token(惟一),這時候要作的操做就是獲取這個token值(appDelegate的代理方法),並將這個token值發送到公司的服務器上去,讓他存儲下來。若是用戶選擇「不容許」,ios 這個操做系統將不會告訴apns這個服務器,那麼到這一步也就完結了。app

     咱們的服務器拿到token值後也不是隨意就能向設備發送推送的,還須要一個證實身份的文件——推送證書,有了這個推送證書後,當有事情發生時,服務器即可以主動向用戶發送遠程推送了
socket

     下面來說解一下這個過程post

2、在程序上註冊遠程通知

   在 didFinishLaunchingWithOptions 裏寫上 :測試

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

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    
    //後面的具體操做省略,程序員們可自由發揮
}


這樣寫就是會提醒,在程序上顯示通知數,推送的過程當中有鈴聲。


經過:

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

代理方法來獲取 device token,在這裏,通常進行的是post請求,將deviceToken值發給服務器

注意:咱們拿到的deviceToken 是帶有空格的,交給服務器時,咱們要將空格去掉(這也能夠交給服務器來作)


當收到遠程通知時,將調用以下代理方法:

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

   //這裏書寫的代碼應該可讓程序進入到相關的頁面


}



3、申請推送證書

一、申請本地證書:

選擇 :

    ——>         ——>   

點擊「鑰匙串訪問」

而後選擇「從證書頒發機構請求證書,如圖:


看到以下界面,郵箱填一個你本身的:


這邊名字隨便起一個


而後點擊繼續在桌面上就生成了一個證書了(申請一個就足夠了):


二、在開發者網站上申請證書

打開99美圓開發者帳號,進入到申請證書的頁面:


點擊「證書」:



選擇App IDs

找到你想發送遠程推送的那一個App ID,點擊它:


點擊"edit」 進行編輯,看到以下界面:


將Push Notifications 的 「」 勾上,選擇下面的 「Create Certification」 ,將剛剛申請的本地證書上傳上去:


點擊Continue :


最後將其下載下來,這裏只示範開發證書,不示範發佈證書的申請了,兩個證書都申請好了以後,再次點擊「edit」能夠看到以下界面:

到這裏,申請證書的工做就算完成了。


4、申請描述文件(開發和發佈描述文件)

下面以開發描述文件爲例,發佈描述文件步驟相同

如圖,選擇申請開發描述文件:



這裏要選擇咱們用於推送的app 的app id


選擇」continue「 選擇證書



將設備所有選上 


最後給描述文件起一個名字,並下載下來

點擊生成後,下載雙擊安裝就完成了。


5、爲服務器製做證書

一、準備p12文件

下面只製做push開發證書,push 發佈證書的製做過程是同樣的,不一樣之處,下文會說明。

雙擊點擊剛剛安裝的下載的證書,這樣證書就進去到鑰匙串裏面去了,在鑰匙串的中找到那一個證書,將其導出爲.p12文件,如圖:


最好創建一個文件夾將全部的證書放在同一個地方,由於最後生成的證書也是在那個位置,給p12取一個名字,存到指定文件夾中:


點擊「存儲」以後要輸入一個密碼,這個密碼隨便輸一個,可是要記住,由於在接下來的步驟中要用得上

在桌面上創建了一個叫「通知」的文件夾,裏面放着全部的證書,如圖:


這樣p12就準備好了


二、將下載的證書製做成.pem 文件

打開終端應用程序,訪問到你證書存放的那個目錄下(如訪問到桌面「通知」文件夾,在終端輸入:

cd /Users/aec/Desktop/通知  ):


輸入後敲回車

進到文件夾目錄後,輸入如下命令將證書轉換成.pem文件:

openssl x509 -in 證書名字.cer -inform der -out push_developer_cer.pem

如圖:


能夠看到文件夾裏多了一個.pem文件:


三、將.p12 證書製做成.pem文件

在終端輸入:

openssl pkcs12 -nocerts -out pushKey.pem -in p12名字.p12


如圖:

敲入回車後,會讓你輸入p12的密碼,這個密碼你輸出來數看不見的,可是你確實輸了,輸完後在敲回車

接下來會讓你輸入兩次新生成的.pem文件的密碼,這個密碼也是看不見的(這個密碼之後要給服務器使用,要牢記)如圖:

能夠看到,文件夾又生成了一個新的文件:pushKey.pem


四、合併兩個.pem文件

將上述新產生的文件合併,在終端輸入命令後敲回車:

cat 下載證書生成的.pem p12生成的.pem > 最終證書的名字.pem

如圖:

能夠看到,文件夾又生成了一個新的文件:final_Push_developer.pem(這個密碼要記住是pushKey.pem生成時要輸入的密碼,密碼須要給到服務器


五、測試證書是否有效

在終端輸入(開發用的驗證):

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert 下載證書生成的.pem -key p12生成的.pem


若是是發佈證書的驗證,輸入:

openssl s_client -connect gateway.push.apple.com:2195 -cert 下載證書生成的.pem -key p12生成的.pem


以後會讓你輸入密碼,輸入密碼後,會有大量openssl消息,當你任意輸入幾個字符時,服務器會提示斷開

如圖:


以上省略若干行後出現下圖:

這時候你就能夠把final_Push_developer.pem 和相應的密碼 交給服務器端了,告訴他們這個證書是沒有問題的


6、php 的服務端實現的代碼:

如下php代碼能夠直接交給服務器,或者讓他們本身寫均可以

<?php  
    $deviceToken= 'da6d8206503c8e62e68b5df1b36c3b58ced1588c6dabe0fc9e6828961aeb36d9'; //沒有空格  
    $body = array("aps" => array("alert" => '推送的內容',"badge" => 1,"sound"=>'default'));  //推送方式,包含內容和聲音  
    $ctx = stream_context_create();  
    
    //若是在Windows的服務器上,尋找pem路徑會有問題,路徑修改爲這樣的方法:  
    //$pem = dirname(__FILE__) . '/' . 'apns-dev.pem';  
    //linux 的服務器直接寫pem的路徑便可  
    
    stream_context_set_option($ctx,"ssl","local_cert","26ck.pem");  
    $pass = "123123";  
    stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);  
    
    //此處有兩個服務器須要選擇,若是是開發測試用,選擇第二名sandbox的服務器並使用Dev的pem證書,若是是正是發佈,使用Product的pem並選用正式的服務器  
   // $fp = stream_socket_client("ssl://gateway.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);  
    $fp = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);  
    
    if (!$fp) {  
        echo "Failed to connect $err $errstrn";  
        return;  
    }  
    
    print "Connection OK\n";  
    $payload = json_encode($body);  
    
    //這邊能夠弄一個循環實現多個deviceToken 值,這裏暫用一個token值得方法
    $msg = chr(0) . pack("n",32) . pack("H*", str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;  
    echo "sending message :" . $payload ."\n";  
    fwrite($fp, $msg);  
    fclose($fp);
?>
相關文章
相關標籤/搜索