iOS 推送

最近在研究ios的推送問題,遇到了一些問題,最終整理了一下。放在這里和大家分享
APNS的推送機制
首先我們看一下蘋果官方給出的對ios推送機制的解釋。如下圖


?
Provider就是我們自己程序的后臺服務器,APNS是Apple Push Notification Service的縮寫,也就是蘋果的推送服務器。
上圖可以分為三個階段:
第一階段:應用程序的服務器端把要發送的消息、目的iPhone的標識打包,發給APNS。
第二階段:APNS在自身的已注冊Push服務的iPhone列表中,查找有相應標識的iPhone,并把消息發送到iPhone。
第三階段:iPhone把發來的消息傳遞給相應的應用程序,并且按照設定彈出Push通知。
?
APNS推送通知的詳細工作流程
下面這張圖是說明APNS推送通知的詳細工作流程:
?

根據圖片我們可以概括一下:
1、應用程序注冊APNS消息推送。
2、iOS從APNS Server獲取devicetoken,應用程序接收device token。
3、應用程序將device token發送給程序的PUSH服務端程序。
4、服務端程序向APNS服務發送消息。
5、APNS服務將消息發送給iPhone應用程序。
?
準備工作
首先要有一臺蘋果的設備,模擬器是不支持推送的,所以你需要一臺iphone,ipod touch或者ipad。
?
我們的客戶端與蘋果服務器之間和我們自己的服務器與蘋果服務器之間都需要證書來進行鏈接。下面我們來開始進入證書的制作過程。
?
一 CSR文件
首先我們要有生成一個Certificate Signing Request(也就是CSR)的請求文件。
在應用程序里的使用工具中找到鑰匙串訪問。

選擇從證書頒發機構請求證書

填上你的郵箱和常用名,常用名要記一下,一會會用到。然后選擇保存到磁盤,繼續

保存位置在桌面,點擊存儲。


到這里點擊完成后我們會在桌面上看到一個CertificateSigningRequest.certSigningRequest的請求文件,也就是我們說的CSR文件。在我們生成CSR文件的同時,會在鑰匙串訪問中生成一對秘鑰,名稱為剛才我們填寫的常用名
?
二 下載開發證書和發布證書
(這里我為了大家能看清楚,已經把之前的證書事先吊銷了)
到https://developer.apple.com/devcenter/ios/index.action登錄后,在右側的ios Developer Program里點擊iOS Provisioning Portal。
進入下一級頁面后在左側選擇Certificates

點擊紅色的部分生成一個開發證書

點擊選擇文件,選擇剛才我們生成到桌面的CSR請求文件。
注意,如果你在后面測試的時候出現了問題,請檢查一下這里,這里的CSR請求文件必須是我們剛才生成的那個


選擇完成后點擊Submit提交

提交完成后返回頁面。頁面會是這樣的,然后我們刷新一下頁面

刷新后會出現一個下載按鈕,我們點擊下載。現在我們的開發證書已經配置并下載好了,發布證書的配置過程和開發證書是一致的,不再贅述。下載完后雙擊,會跳到鑰匙串訪問里。這就是我們之后要進行測的證書
?
三 配置AppID,配置并下載SSL證書
點擊左側的App IDs,找到我們要做推送功能的程序的id(如果沒有的話要先New一個。注意,這里的App ID必須不能是通配的,通配的不可以做推送)。點擊Configure

進入后默認推送功能是關閉的,我們需要把推送功能打開

選中打開后,點擊右邊灰色的Configure按鈕


這里的文件同樣的,還是選擇我們生成在桌面上的CSR請求文件



然后點擊繼續

出現了我們需要的SSL證書,我們點擊下載后點擊Done完成。

Status狀態變成了綠色可用了。這里右邊的下載和上一步的下載是一樣的,如果在上一步中下載了證書,便無需再次下載。此時我們有了一個名字叫aps_development.cer的SSL證書,同樣,我們把他放在桌面。雙擊后會跳到鑰匙串訪問,出現我們的SSL推送證書
同樣的,發布的SSL證書的步驟也是一樣的。
?
四 下載Provisioning證書
在左側選擇Provisioning

配置好后點擊提交(注意App ID要與我們剛的程序對應)
之后變回出現下載按鈕,我們點擊下載。下載后雙擊,并將我們的設備上的描述文件更新一下(最好把之前的全部刪除,然后再安裝,防止出錯)。
?
五 從鑰匙串訪問中導出秘鑰
打開鑰匙串訪問,找到我們的專用秘鑰(專用秘鑰的名稱就是我們在最開始生成CSR請求的時候填寫的常用名)

右鍵選擇導出

導出的文件名我們叫做Push

在這里需要輸入一個密碼來對文件進行加密。這里我們選擇abcabc,當然你也可以自己選擇是什么,但是這個密碼必須要銘記,切記!

然后輸入你電腦的密碼,點擊允許。
這樣我們就在桌面上生成了一個Push.p12文件。
?
到此為止,我們在桌面上一共生成了三個文件。一個是CSR請求文件,一個是aps_development .cer的SSL證書文件,還有一個剛才生成的Push.p12秘鑰文件。
?
現在我們的準備工作已經做完了。要開始對生成的文件進行處理了。原因上面已經解釋過,因為我們的服務鏈接蘋果服務器也是需要證書的,但是我們直接生成的證書windows系統(我們一般的服務器都是win系統的)是不識別的,所以我們需要生成一個后綴為pem的帶證書帶秘鑰的文件。
?
六 處理證書
下面我們打開終端(位置:應用程序à實用工具à終端)。
cd到桌面,我們那三個文件所在的位置
?
1、把.cer的SSL證書轉換為.pem文件,執行命令:
openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
在桌面上會生成一個PushChatCert.pem文件

?
2、把私鑰Push.p12文件轉化為.pem文件:
openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
?
這里需要我們輸入密碼,這個密碼也就是我們導出p12文件時的密碼,也就是我們上面設置的abcabc。然后,需要我們對生成的pem文件設置一個密語,這里我們推薦還是用上面這個abcabc,防止混亂(當然你也可以設置成別的更有意義的密語),這里的密語是要告訴我們服務器的。這樣,桌面上又會生成一個PushChatKey.pem文件

3、對生成的這兩個pem文件再生成一個pem文件,來把證書和私鑰整合到一個文件里:
cat PushChatCert.pem PushChatKey.pem > ck.pem
生成ck.pem文件
?
這樣,我們的文件就制作完了。下面進入測試階段
為了測試證書是否工作,執行下面的命令:
telnet gateway.sandbox.push.apple.com 2195
它將嘗試發送一個規則的,不加密的連接到APNS服務。如果你看到上面的反饋,那說明你的MAC能夠到達APNS。按下Ctrl+C關閉連接。如果得到一個錯誤信息,那么你需要確保你的防火墻允許2195端口。一般這里都不會出現什么問題。
?
下面我們要使用我們生成的SSL證書和私鑰來設置一個安全的鏈接去鏈接蘋果服務器:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem
執行完這一句命令后需要我們輸入密語
Enter pass phrase for PushChatKey.pem:
我們輸入abcabc按回車
你會看到一個完整的輸出,讓你明白OpenSSL在后臺做什么。如果鏈接是成功的,你可以隨便輸入一個字符,按下回車,服務器就會斷開鏈接,如果建立連接時有問題,OpenSSL會給你返回一個錯誤信息。
?當你在最后的時候你看到這樣說明你已經成功了:
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)
---
在這里提醒一下,也許你會看到像我這樣的提示:verify error:num=20:unable to get local issuercertificate
verify return:0
其實是沒問題的。


七 項目測試
建立我們的推送的項目(注意BundleIdentifier必須和我們推送應用的App id一致)
在AppDelegate里didFinishLaunchingWithOptions函數里寫
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
……
? //推送的形式:標記,聲音,提示
?? [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
?? return YES;
}
?
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {
?? NSLog(@"regisger success:%@",pToken);
?? //注冊成功,將deviceToken保存到應用服務器數據庫中
}
- (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);
}
我們運行程序的時候會有提示,說我們的程序要發送推送通知
?
?
下面我們把php服務器代碼和生成的ck.pem文件放在統一文件夾下面(這里我們還是統一放在桌面上)。
用Xcode打開(其他工具也可以)php服務器端的代碼,把deviceToken改成我們現在要進行測試的iphone的deviceToken(獲得方法:首先運行我們的程序,程序啟動后打印的日志文件里可以看到。感謝 邊玩勺子把兒去 同學的提醒),密語改成我們之前設置的abcabc。然后保存。
然后在終端運行命令(如果剛才你關閉了終端的話,最好ls一下,看看當前是不是在桌面),執行命令:
php pushMe.php
然后回車(pushMe為服務器文件名稱)

如果出現這樣的提示說明成功了,然后在iphone上,我們期待已久的推送消息終于來了。
以下是推送的幾種效果:


?
常見問題:
1、在用證書和秘鑰鏈接服務器時出現提示:
Error opening client certificate private key filePushChatKey.pem
20839: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文件路徑下再進行鏈接
?
2、前期測試沒有問題,將ck.pem給服務器,通過服務器進行推送時推送不成功,提示鏈接APNS失敗。
解決:一,看一下證書的名稱,密語是否正確;二,路徑是否正確;然后檢查一下庫,OpenSSL和libssl;此外apache還要開啟OpenSSL權限,確保可以訪問pem
?
3、APNS地址
測試地址gateway.sandbox.push.apple.com:2195
發布地址 gateway.push.apple.com:2195
測試的地址用的是沙盒,發布地址是不同的。發布軟件的時候記得改過來

4、要注意順序問題,一定要按照這個順序來:
生成鑰匙串請求 -->配置下載開發證書-->? 配置App ID ,配置、下載SSL證書-->Provisioning證書

5、多注意一下紅色字體部分

在此感謝曾經為此而努力過的前輩們,尤其是感謝楊大哥的幫助。
在這里附上楊大哥的帖子:http://www.cocoachina.com/bbs/read.php?tid=102110&page=1
?
另外附上幾個關于推送的不錯的帖子:
http://zxs19861202.iteye.com/blog/1532460
一篇很不錯的帖子,老外寫的
http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12
中文翻譯
http://article.ityran.com/archives/194
?
在過程中如果有疑問可以新浪或騰訊微博@showhilllee雖然本人是菜鳥一個,也許不能為你把問題解決掉,但是會本著菜鳥精神去幫你解決
?
轉帖請注明出處:http://blog.csdn.net/showhilllee/article/details/8631734

php服務器代碼pushMe.php:?? http://download.csdn.net/detail/showhilllee/7208681
本文若有問題,歡迎大家斧正

官方文檔地址:https://developer.apple.com/library/ios/technotes/tn2265/_index.html

全面的推送博客:http://54im.com/ios/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E9%85%8D%E7%BD%AE%E8%8B%B9%E6%9E%9Capns%E6%8E%A8%E9%80%81%E6%9C%8D%E5%8A%A1.html

集成信鴿推送:http://www.jianshu.com/p/f464b72b106c
?
14年10月27號補充:
1、這里說下php代碼問題,有些童鞋反饋說收不到消息,我記得以前測試的時候確實會有這種情況,至于原因一個是可能超時了(蘋果推送也會超時的),另一個就是不明原因了。另外注意下以下幾點:
1)、記得修改deviceToken,要換成你自己的
2)、修改密語
3)、生成的pem文件名稱
4)、查看下當前連接的是蘋果推送的測試地址還是正式地址
2、iOS8以上版本注冊推送方式已經變更
[[UIApplicationsharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings
??????????????????????????????????????????????????????????????????????????? settingsForTypes:(UIUserNotificationTypeSound |UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
??????????????????????????????????????????????????????????????????????????? categories:nil]];
??????? [[UIApplicationsharedApplication]registerForRemoteNotifications];

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458548.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458548.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458548.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Bash判斷文件夾(目錄)是否存在

1 #!/bin/bash 2 if [ -d DirName ]; then 3 echo Dir exist 4 else 5 echo Dir not exist 6 fi 轉載于:https://www.cnblogs.com/imzye/p/5059031.html

iOS 加載本地html文件詳細操作

webView的加載,如果是純文本,有內部樣式的話,簡單的加載請求就可以了。如下: 這種加載簡單直接,易操作。 如果需要加載images,css文件 需要把xcode的項目請求路徑的位置告訴webView.代碼如下: 這樣html文件…

HDU 5573 Binary Tree 構造

Binary Tree題目連接: http://acm.hdu.edu.cn/showproblem.php?pid5573 Description The Old Frog King lives on the root of an infinite tree. According to the law, each node should connect to exactly two nodes on the next level, forming a full binary…

志邦櫥柜坑爹,志邦櫥柜大忽悠,志邦櫥柜欺騙

本人實實在在經歷的,志邦櫥柜就是個大忽悠,志邦櫥柜沒誠信!! 志邦櫥柜先騙客戶下訂單,在預算時低開,到真正簽合同時,不僅僅尺寸坑你,一大堆增項都會出來,原本1.5w預算到最后簽合同總價到2.2w,簽合同增項高開最后志邦櫥柜總價超預算非常非常離譜&#xff…

多線程的那點兒事(之讀寫鎖)

在編寫多線程的時候,有一種情況是十分常見的。那就是,有些公共數據修改的機會比較少。相比較改寫,它們讀的機會反而高的多。通常而言,在讀的過程中,往往伴隨著查找的操作,中間耗時很長。給這種代碼段加鎖&a…

iOS獲取設備IP

獲取iOS設備IP wifi和流量環境下 在網上找的比較好的獲取ip的代碼 #include <ifaddrs.h> #include <arpa/inet.h> #include <net/if.h> #define IOS_CELLULAR "pdp_ip0" #define IOS_WIFI "en0" #define IOS_VPN …

一些不錯的網站

http://www.huxiu.com/虎嗅網&#xff0c;一個關注最新創業信息的網站http://36kr.com/創業天花板https://www.zhihu.com/與世界分享你的經驗http://www.mafengwo.cn/世界那么大&#xff0c;想去哪就去那http://www.mt-bbs.com/找到屬于自己的設計本http://www.guokr.com/科技有…

[原]詳解如何將cocos2dx項目編譯到Android平臺上的(方式一:Cywin+NDK)

鏈接地址&#xff1a;http://m.blog.csdn.net/blog/yhc13429826359/29357815 2014-6-8閱讀578 評論0 前言&#xff1a;cocos2dx作為一個開源的移動2D游戲框架&#xff0c;其跨平臺的特性讓它備受開發公司的歡迎。這里我就不做概念性的解釋了&#xff0c;通過這篇文章你就會了解…

互斥鎖和讀寫鎖的區別

原文地址&#xff1a;http://blog.csdn.NET/u012884354/article/details/46691761 相交進程之間的關系主要有兩種&#xff0c;同步與互斥。 所謂互斥&#xff0c;是指散布在不同進程之間的若干程序片斷&#xff0c;當某個進程運行其中一個程序片段時&#xff0c;其它進程就不能…

JSP EL表達式使用

為什么80%的碼農都做不了架構師&#xff1f;>>> ##1.EL全名為Expression Language out.print(str) <%str%> ${str}例子&#xff1a; Hi! <%username%> 和 Hi! ${username}是一樣的 只要是支持servlet2.4/jsp2.0的Container就都可以在jsp網頁中直接使用e…

eclipse 中 Android sdk 無法更新的問題

誒&#xff0c;真是麻煩&#xff0c;想下個東西都下不了。我也好久沒折騰過這個了&#xff0c;在家的電腦是早就下載好了的&#xff0c;然后如今又須要下載一份。下不到。網上搜到了資料&#xff0c;記錄下來&#xff1a; 第一種方法:sdk manager - tools - option 選擇強制 xx…

iOS10 xcode8 分頁請求MJRefresh崩潰問題

MJRefresh出現崩潰現象 解決辦法&#xff1a;類庫增加判斷 if (range.location ! NSNotFound) { language [language substringToIndex:range.location]; }

網絡編程學習筆記一:Socket編程

from: http://blog.csdn.net/gneveek/article/details/8699198 “一切皆Socket&#xff01;” 話雖些許夸張&#xff0c;但是事實也是&#xff0c;現在的網絡編程幾乎都是用的socket。 ——有感于實際編程和開源項目研究。 我們深諳信息交流的價值&#xff0c;那網絡中進程之間…

JavaScript原生對象常用方法總結

這是4年前學習JavaScript基礎的學習筆記&#xff0c;當初是照著W3School教程學習的&#xff0c;4年恍然如云煙&#xff0c;仿佛還在昨天。現發布與此&#xff0c;留作紀念&#xff0c;紀念那段不悔的青蔥歲月。下面都是我學習W3C School教程中有關JavaScript寫的學習筆記&#…

[delphi]修改indy源碼后重新編譯

http://blog.csdn.net/nerdy/article/details/8702568 雖然indy有一身的毛病&#xff0c;但是一般情況下使用起來還是多方便的。 今天在做一個使用到indy的程序的時候&#xff0c;發現無論你怎么修改idhttp.request.accept-encoding&#xff0c;他都會在其后添加一個值 identit…

xcode8 崩潰問題

【1】、Xcode8代碼出現ubsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0 2016-09-14 17:18:…

前端工具--less篇

前端工具–less篇 less 中文網http://www.bootcss.com/p/lesscss/ 常見錯誤及解決&#xff1a; sublime text 3 安裝less2css保存less出現錯誤 未安裝這個 npm install -g less-plugin-clean-css 未安裝這個 npm install less -gd less語法 LESS 做為 CSS 的一種形式的擴展&a…

從static變量導出問題解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

這段時間要把tinyxml從靜態庫弄成動態庫&#xff0c;要用到__declspec(dllexport)和__declspec(dllimport)來導出dll和lib文件。終于弄明白了export和import的作用&#xff0c;下面從使用的角度來說明一下他們的功能。 首先要知道&#xff0c;頭文件是C的接口文件&#xff0c;不…

4月26日作業

2016年4月26日作業 一、項目整體績效評估1、*三E審計是什么的合稱&#xff1f;&#xff08;記&#xff09; 答&#xff1a;經濟審計&#xff0c;效率審計和效果審計2、霍爾三維結構是從哪三個方面考察系統工程的工作過程的&#xff1f; 答&#xff1a;邏輯&#xff0c;時間和知…

xcode8 快捷鍵失效

因為蘋果解決xcode ghost,把插件屏蔽了。 解決方法: 命令運行&#xff1a; sudo /usr/libexec/xpccachectl 然后必須重啟電腦后生效