前言:現(xiàn)在第三方推送也很多 蟀悦,比如極光,融云渴丸,信鴿侯嘀,其原理也是相同利用APNS推送機(jī)制 ,前段公司讓做自己的推送谱轨,1.避免device token被第三方泄露戒幔,保護(hù)手機(jī)設(shè)備信息,2.第三方部分開始收費(fèi)土童,一些免費(fèi)的以后誰又知道呢 溪食,不如自己創(chuàng)建,除了后臺(tái)麻煩點(diǎn)娜扇,需要數(shù)據(jù)庫來存儲(chǔ)token相關(guān)字段(后臺(tái)配置部分在最后更新添加)错沃,前端實(shí)現(xiàn)起來并不復(fù)雜 栅组。 對于iOS8.0以后,原生推送實(shí)時(shí)性很好枢析,也解決了第三方SDK占用存儲(chǔ)顧慮玉掸,何樂不為呢!這篇文章將很詳細(xì)的講解它 只要按照一步一步來很容易實(shí)現(xiàn) 醒叁。先從推送機(jī)制開始
首先我們看一下蘋果官方給出的對iOS推送機(jī)制的解釋司浪。如下圖
Provider就是我們自己程序的后臺(tái)服務(wù)器,APNS是Apple Push Notification Service的縮寫把沼,也就是蘋果的推送服務(wù)器啊易。
上圖可以分為三個(gè)階段:
第一階段:應(yīng)用程序的服務(wù)器端把要發(fā)送的消息、目的iPhone的標(biāo)識(shí)打包饮睬,發(fā)給APNS租谈。
第二階段:APNS在自身的已注冊Push服務(wù)的iPhone列表中,查找有相應(yīng)標(biāo)識(shí)的iPhone捆愁,并把消息發(fā)送到iPhone割去。
第三階段:iPhone把發(fā)來的消息傳遞給相應(yīng)的應(yīng)用程序,并且按照設(shè)定彈出Push通知昼丑。
APNS推送通知的詳細(xì)工作流程
下面這張圖是說明APNS推送通知的詳細(xì)工作流程:
根據(jù)圖片我們可以概括一下:
1呻逆、應(yīng)用程序注冊APNS消息推送。
2菩帝、ios從APNS Server獲取devicetoken咖城,應(yīng)用程序接收device token。
3呼奢、應(yīng)用程序?qū)evice token發(fā)送給程序的PUSH服務(wù)端程序酒繁。
4、服務(wù)端程序向APNS服務(wù)發(fā)送消息控妻。
5州袒、APNS服務(wù)將消息發(fā)送給iPhone應(yīng)用程序。
準(zhǔn)備工作
首先要有一臺(tái)蘋果的設(shè)備弓候,模擬器是不支持推送的郎哭,所以你需要一臺(tái)iphone,ipod touch或者ipad菇存。
我們的客戶端與蘋果服務(wù)器之間和我們自己的服務(wù)器與蘋果服務(wù)器之間都需要證書來進(jìn)行鏈接夸研。下面我們來開始進(jìn)入證書的制作過程。
首先蘋果證書主要分為上線證書和測試證書依鸥,相信都有所了解 在此不再累贅了 亥至,接下來就開始制作吧
一 CSR文件
首先我們要有生成一個(gè)Certificate Signing Request(也就是CSR)的請求文件。
在應(yīng)用程序里的使用工具中找到鑰匙串訪問。
Snip20160728_10.png
填上你的郵箱和常用名 或者是公司關(guān)聯(lián)賬號姐扮,常用名要記一下絮供,一會(huì)
會(huì)用到。
Snip20160728_13.png
然后選擇保存到磁盤茶敏,繼續(xù)
Snip20160728_15.png
這時(shí)桌面上會(huì)有一個(gè)CertificateSigningRequest.certSigningRequest的請求文件壤靶,也就是我們說的CSR文件。在我們生成CSR文件的同時(shí)惊搏,會(huì)在鑰匙串訪問中生成一對秘鑰贮乳,名稱為剛才我們填寫的常用名
二 下載開發(fā)證書和發(fā)布證書
到https://developer.apple.com/devcenter/ios/index.action登錄后,在右側(cè)的ios Developer Program里點(diǎn)擊iOS Provisioning Portal。
進(jìn)入下一級頁面后在左側(cè)選擇Certificates
點(diǎn)擊紅色的部分生成一個(gè)開發(fā)證書
點(diǎn)擊選擇文件恬惯,選擇剛才我們生成到桌面的CSR請求文件向拆。
注意,如果你在后面測試的時(shí)候出現(xiàn)了問題酪耳,請檢查一下這里浓恳,這里的CSR請求文件必須是我們剛才生成的那個(gè)
選擇完成后點(diǎn)擊Submit提交
提交完成后返回頁面。頁面會(huì)是這樣的葡兑,然后我們刷新一下頁面
刷新后會(huì)出現(xiàn)一個(gè)下載按鈕奖蔓,我們點(diǎn)擊下載≡薏荩現(xiàn)在我們的開發(fā)證書已經(jīng)配置并下載好了讹堤,發(fā)布證書的配置過程和開發(fā)證書是一致的,不再贅述厨疙。下載完后雙擊洲守,會(huì)跳到鑰匙串訪問里。這就是我們之后要進(jìn)行測的證書
三 配置AppID沾凄,配置并下載SSL證書
點(diǎn)擊左側(cè)的App IDs梗醇,找到我們要做推送功能的程序的id(如果沒有的話要先New一個(gè)。注意:這里的App ID必須不能是通配的撒蟀,通配的不可以做推送)
點(diǎn)擊Configure
進(jìn)入后默認(rèn)推送功能是關(guān)閉的叙谨,我們需要把推送功能打開
選中打開后,點(diǎn)擊右邊灰色的Configure按鈕
這里的文件同樣的保屯,還是選擇我們生成在桌面上的CSR請求文件
然后點(diǎn)擊繼續(xù)
出現(xiàn)了我們需要的SSL證書手负,我們點(diǎn)擊下載后點(diǎn)擊Done完成。
Status狀態(tài)變成了綠色可用了姑尺。這里右邊的下載和上一步的下載是一樣的竟终,如果在上一步中下載了證書,便無需再次下載切蟋。此時(shí)我們有了一個(gè)名字叫aps_development.cer的SSL證書统捶,同樣,我們把他放在桌面。雙擊后會(huì)跳到鑰匙串訪問喘鸟,出現(xiàn)我們的SSL推送證書
同樣的匆绣,發(fā)布的SSL證書的步驟也是一樣的。
四 下載Provisioning證書
在左側(cè)選擇Provisioning
配置好后點(diǎn)擊提交(注意App ID要與我們剛的程序?qū)?yīng))
之后變回出現(xiàn)下載按鈕迷守,我們點(diǎn)擊下載犬绒。下載后雙擊,并將我們的設(shè)備上的描述文件更新一下(最好把之前的全部刪除兑凿,然后再安裝凯力,防止出錯(cuò))。
五 從鑰匙串訪問中導(dǎo)出秘鑰
打開鑰匙串訪問礼华,找到我們的專用秘鑰(專用秘鑰的名稱就是我們在最開始生成CSR請求的時(shí)候填寫的常用名)
右鍵選擇導(dǎo)出
導(dǎo)出的文件名我們叫做Push
在這里需要輸入一個(gè)密碼來對文件進(jìn)行加密咐鹤。這里我們選擇abc123,當(dāng)然你也可以自己選擇是什么圣絮,但是這個(gè)密碼必須要銘記祈惶,切記!
然后輸入你電腦的密碼扮匠,點(diǎn)擊允許捧请。
這樣我們就在桌面上生成了一個(gè)Push.p12文件。
到此為止棒搜,我們在桌面上一共生成了三個(gè)文件疹蛉。一個(gè)是CSR請求文件,一個(gè)是aps_development .cer的SSL證書文件力麸,還有一個(gè)剛才生成的Push.p12秘鑰文件可款。
現(xiàn)在我們的準(zhǔn)備工作已經(jīng)做完了。要開始對生成的文件進(jìn)行處理了克蚂。原因上面已經(jīng)解釋過闺鲸,因?yàn)槲覀兊姆?wù)鏈接蘋果服務(wù)器也是需要證書的,但是我們直接生成的證書windows系統(tǒng)(我們一般的服務(wù)器都是win系統(tǒng)的)是不識(shí)別的埃叭,所以我們需要生成一個(gè)后綴為pem的帶證書帶秘鑰的文件摸恍。
六 處理證書
下面我們打開終端(位置:應(yīng)用程序à實(shí)用工具à終端)。
cd到桌面赤屋,我們那三個(gè)文件所在的位置
1立镶、把.cer的SSL證書轉(zhuǎn)換為.pem文件,執(zhí)行命令:
openssl x509 -inaps_development.cer-inform der -outPushChatCert.pem
在桌面上會(huì)生成一個(gè)PushChatCert.pem文件
2益缎、把私鑰Push.p12文件轉(zhuǎn)化為.pem文件:
openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
這里需要我們輸入密碼谜慌,這個(gè)密碼也就是我們導(dǎo)出p12文件時(shí)的密碼,也就是我們上面設(shè)置的abc123莺奔。然后欣范,需要我們對生成的pem文件設(shè)置一個(gè)密語变泄,這里我們推薦還是用上面這個(gè)abcabc,防止混亂(當(dāng)然你也可以設(shè)置成別的更有意義的密語),這里的密語是要告訴我們服務(wù)器的恼琼。這樣妨蛹,桌面上又會(huì)生成一個(gè)PushChatKey.pem文件
3、對生成的這兩個(gè)pem文件再生成一個(gè)pem文件晴竞,來把證書和私鑰整合到一個(gè)文件里:
catPushChatCert.pem PushChatKey.pem>ck.pem
生成ck.pem文件
這樣蛙卤,我們的文件就制作完了。下面進(jìn)入測試階段
為了測試證書是否工作噩死,執(zhí)行下面的命令:
telnet gateway.sandbox.push.apple.com 2195
它將嘗試發(fā)送一個(gè)規(guī)則的颤难,不加密的連接到APNS服務(wù)。如果你看到上面的反饋已维,那說明你的MAC能夠到達(dá)APNS行嗤。按下Ctrl+C關(guān)閉連接。如果得到一個(gè)錯(cuò)誤信息垛耳,那么你需要確保你的防火墻允許2195端口栅屏。一般這里都不會(huì)出現(xiàn)什么問題。
下面我們要使用我們生成的SSL證書和私鑰來設(shè)置一個(gè)安全的鏈接去鏈接蘋果服務(wù)器:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem
執(zhí)行完這一句命令后需要我們輸入密語
Enter pass phrase for PushChatKey.pem:
我們輸入abcabc按回車
你會(huì)看到一個(gè)完整的輸出堂鲜,讓你明白OpenSSL在后臺(tái)做什么栈雳。如果鏈接是成功的,你可以隨便輸入一個(gè)字符缔莲,按下回車哥纫,服務(wù)器就會(huì)斷開鏈接,如果建立連接時(shí)有問題酌予,OpenSSL會(huì)給你返回一個(gè)錯(cuò)誤信息磺箕。
當(dāng)你在最后的時(shí)候你看到這樣說明你已經(jīng)成功了:
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.NET/rpa isincorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust CertificationAuthority - L1C
verify error:num=20:unable to get local issuercertificate
verify return:0
Certificate chain
0s:/C=US/ST=California/L=Cupertino/O=Apple >Inc./OU=iTMSEngineering/CN=gateway.sandbox.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated byreference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1s:/C=US/O=Entrust, Inc./OU=www.entrust.Net/rpa is incorporated byreference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.netCertification Authority (2048)
Server certificate
-----BEGIN CERTIFICATE-----
MIIFGzCCBAOgAwIBAgIETBz90jANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
……省略……
fMGbLqkGn8YogdPqe5T1
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=AppleInc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa isincorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust CertificationAuthority - L1C
No client certificate CA names sent
SSL handshake has read 2731 bytes and written 2165 bytes
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key:C7A47EED5E1F5……省略……369D4
Key-Arg : None
Start Time:1361862882
Timeout : 300 (sec)
Verify return code: 0 (ok)
在這里提醒一下奖慌,也許你會(huì)看到像我這樣的提示:verify error:num=20:unable to get local issuercertificate
verify return:0
其實(shí)是沒問題的抛虫。
七 項(xiàng)目測試
建立我們的推送的項(xiàng)目(注意BundleIdentifier必須和我們推送應(yīng)用的App id一致)
在AppDelegate里didFinishLaunchingWithOptions函數(shù)里寫- (BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{//推送的形式:標(biāo)記,聲音简僧,提示[[UIApplicationsharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert];returnYES;}- (void)application:(UIApplication*)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData*)pToken {NSLog(@"regisger success:%@",pToken);//注冊成功建椰,將deviceToken保存到應(yīng)用服務(wù)器[數(shù)據(jù)庫](http://lib.csdn.net/base/14)中}- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo{// 處理推送消息NSLog(@"userinfo:%@",userInfo);NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);}- (void)application:(UIApplication*)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError*)error {NSLog(@"Registfail%@",error); }
我們運(yùn)行程序的時(shí)候會(huì)有提示,說我們的程序要發(fā)送推送通知
下面我們把PHP服務(wù)器代碼和生成的ck.pem文件放在統(tǒng)一文件夾下面(這里我們還是統(tǒng)一放在桌面上)岛马。
用Xcode打開(其他工具也可以)php服務(wù)器端的代碼丹诀,把deviceToken改成我們現(xiàn)在要進(jìn)行測試的iphone的deviceToken(獲得方法:首先運(yùn)行我們的程序魄咕,程序啟動(dòng)后打印的日志文件里可以看到。感謝 邊玩勺子把兒去 同學(xué)的提醒),密語改成我們之前設(shè)置的abc123衙伶。然后保存。
然后在終端運(yùn)行命令(如果剛才你關(guān)閉了終端的話垒拢,最好ls一下童漩,看看當(dāng)前是不是在桌面),執(zhí)行命令:
php pushMe.php
然后回車(pushMe為服務(wù)器文件名稱)
如果出現(xiàn)這樣的提示說明成功了,然后在iphone上湿诊,我們期待已久的推送消息終于來了狱杰。
IMG_2759.PNG
1、在用證書和秘鑰鏈接服務(wù)器時(shí)出現(xiàn)提示:
Error opening client certificate private key filePushChatKey.pem20839:error:02001002:system library:fopen:No such file ordirectory:/SourceCache/OpenSSL098/OpenSSL098-44/src/crypto/bio/bss_file.c:356:fopen('PushChatKey.pem','r')
20839:error:20074002:BIO
routines:FILE_CTRL:systemlib:/SourceCache/OpenSSL098/OpenSSL098-44/src/crypto/bio/bss_file.c:358:
unable to load client certificate private key file
解決:
文件路徑不對厅须。cd到生成的pem文件路徑下再進(jìn)行鏈接
2仿畸、前期測試沒有問題,將ck.pem給服務(wù)器朗和,通過服務(wù)器進(jìn)行推送時(shí)推送不成功错沽,提示鏈接APNS失敗。
解決:一眶拉,看一下證書的名稱甥捺,密語是否正確;二镀层,路徑是否正確镰禾;然后檢查一下庫,OpenSSL和libssl唱逢;此外apache還要開啟OpenSSL權(quán)限吴侦,確保可以訪問pem
3坞古、APNS地址 (**一定記住切換地址,好多推送不成功就是地址不對,pushMe.php中的代碼地址我已經(jīng)換成測試的了**)
測試地址gateway.sandbox.push.apple.com:2195
發(fā)布地址 gateway.push.apple.com:2195
測試的地址用的是沙盒备韧,發(fā)布地址是不同的。發(fā)布軟件的時(shí)候記得改過來
4痪枫、要注意順序問題织堂,一定要按照這個(gè)順序來:
生成鑰匙串請求 -->配置下載開發(fā)證書--> 配置App ID ,配置奶陈、下載SSL證書-->Provisioning證書
下載地址:github:https://github.com/one-tea/APNS_test.git
有什么問題可以與我私信易阳,如果喜歡歡迎關(guān)注,更好的東西共享給大家吃粒!
后臺(tái)的配置問題
在這里說下后臺(tái)配置潦俺,主要分兩類:
一.Java、PHP可以通用,上面pushMe.php也就是適用代碼徐勃;
二. 另一種有.net后臺(tái)的(比如我們公司)事示,給后臺(tái)證書為.p12格式 制作方法:
在鑰匙中找到你安裝過的推送證書,記不住就返回上面證書配置那塊看
Snip20160803_12.png
Snip20160803_13.png
導(dǎo)出為.p12僻肖,密鑰也為abc123好了, 這個(gè)秘鑰需要和.p12一起給后臺(tái)
至于后臺(tái)有寫好的代碼 .net 項(xiàng)目中引PushSharp.Apple.dll,PushSharp.Core.dll(這兩個(gè)文件在網(wǎng)上搜一下肖爵,有源碼的)
文/海諾_簡書(簡書作者)
原文鏈接:http://www.reibang.com/p/032bfc949917
著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)臀脏,并標(biāo)注“簡書作者”劝堪。