極光推送:
1.JPush當(dāng)前版本是1.8.2嫁蛇,其SDK的開發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋果官方的步伐害晦,SDK在iOS8剛推出的時(shí)候跟進(jìn)更新询筏。在一定程度上來講,能夠體現(xiàn)極光推送的技術(shù)力量是比較強(qiáng)大的竖慧;
2.應(yīng)用內(nèi)消息提高了推送服務(wù)的及時(shí)性和可靠性嫌套,在、緊隨當(dāng)下追求應(yīng)用實(shí)時(shí)性的潮流圾旨,能夠提供更好的推送服務(wù)的用戶體驗(yàn)踱讨;
3.JPush除了有著完善的控制臺(tái)外,還提供了服務(wù)端的接口砍的,方便開發(fā)者的服務(wù)器調(diào)用痹筛,方便開發(fā)者對于應(yīng)用管理、整合即通過應(yīng)用服務(wù)器極光服務(wù)器推送服務(wù)器用戶設(shè)備廓鞠,簡化了服務(wù)器端的開發(fā)強(qiáng)度帚稠,也方便運(yùn)營期間發(fā)送推送消息的流程;
4.如果開發(fā)者同時(shí)需要用戶統(tǒng)計(jì)和推送功能床佳,那么這是一款不容錯(cuò)過的SDK因?yàn)镴Push提供了全面直觀的統(tǒng)計(jì)數(shù)據(jù)滋早,在控制臺(tái)中以圖表的形式呈現(xiàn),方便運(yùn)營期間的數(shù)據(jù)分析砌们;
5.當(dāng)前版本的SDK僅有5M左右的體積杆麸,嵌入應(yīng)用或者打包應(yīng)用影響都是很小的,開發(fā)者大可不必?fù)?dān)心浪感。
6.對于高級(jí)用戶還開放了富媒體推送和更多的API調(diào)用次數(shù)角溃,當(dāng)然這也需要開發(fā)者付出一定的費(fèi)用,對于有需要的開發(fā)者可以自行了解篮撑。
綜合評(píng)價(jià):
筆者在測試極光推送之前也測試過其他的推送服務(wù)减细,在項(xiàng)目中使用的也是極光推送。對比這些推送服務(wù)來講赢笨,極光是從文檔未蝌、SDK簡潔程度驮吱、集成難度、服務(wù)都較為滿意的萧吠。在筆者的應(yīng)用中有需要統(tǒng)計(jì)用戶行為的需求左冬,而極光也恰恰滿足了這種需求,帶來了極大的方便纸型∧磁椋總而言之,極光推送確實(shí)能給開發(fā)者帶來不錯(cuò)的編程體驗(yàn)狰腌。
通過筆者的測試除破,極光SDK的集成難度不大,文檔注釋清晰易懂琼腔。而且有較為強(qiáng)大的技術(shù)支持(QQ群瑰枫、論壇、博客)丹莲。所以對于有一定開發(fā)經(jīng)驗(yàn)的需要使用推送服務(wù)光坝、本地推送服務(wù)、推送統(tǒng)計(jì)的開發(fā)者是非常適用的甥材,而即使是對推送要求不高的項(xiàng)目盯另,極光SDK的開發(fā)成本也并不是很高,所以具有較為寬泛的適用范圍洲赵。
極光推送是推送服務(wù)商中較大的一個(gè)土铺,目前的用戶量也相當(dāng)龐大,其文檔板鬓、注釋悲敷、網(wǎng)站控制臺(tái)都較為完善。極光SDK對推送服務(wù)進(jìn)行高級(jí)封裝俭令,除了實(shí)現(xiàn)APNS推送以外還實(shí)現(xiàn)了基于TCP連接的應(yīng)用內(nèi)消息后德,在一定程度上提高了推送服務(wù)的可靠性。其SDK非常簡潔抄腔,簡化了集成過程瓢湃,而通過閱讀API的注釋及相關(guān)文檔控轿,開發(fā)者可以很快的掌握SDK的使用雁竞。對于有一定開發(fā)經(jīng)驗(yàn)的開發(fā)者是非常易于上手的
高送達(dá)率咖耘,時(shí)效保證:極光推送自主協(xié)議確認(rèn)推送消息的送達(dá)豺谈。開發(fā)者可以靈活的自定義推送時(shí)間
服務(wù)集成SDK簡單:簡單復(fù)制便可直接編譯運(yùn)行
推送內(nèi)容多樣性服務(wù):除了通知,還有消息沃饶、多媒體等
使你的應(yīng)用程序保持高注意力:即使用戶沒有打開應(yīng)用程序胰锌,極光推送也能夠推送通知到達(dá)用戶手機(jī)
自定義消息內(nèi)容:JPushSDK把內(nèi)容完全轉(zhuǎn)給應(yīng)用程序治泥,由開發(fā)者應(yīng)用程序去處理自定義消息
接入即可用功能:客戶端集成SDK即可享受高效?專業(yè)的推送服務(wù),操作簡單的管理后臺(tái)
多平臺(tái):同時(shí)支持?Android與iOS平臺(tái)
高安全性:傳輸信道加密,推送數(shù)據(jù)自主加密
高穩(wěn)定性筏勒,大容量移迫,高并發(fā):目前極光推送平臺(tái)支持?十億級(jí)用戶,高達(dá)20萬/秒的下行速度
省流量管行,低耗電功能強(qiáng)大:待機(jī)流量消耗20K/天厨埋,電?量消耗30mAh/天? 畢竟國外網(wǎng)絡(luò)服務(wù)在中國都頗為不完善,而且推送服務(wù)對網(wǎng)絡(luò)和服務(wù)器端有較高的要求捐顷。因此荡陷,國內(nèi)很快就興起數(shù)家像極光推送云消息推送服務(wù)的公司,是國內(nèi)做得較好的一家迅涮。
優(yōu)勢:
1)? ?開放注冊废赞,免費(fèi)向所有的開發(fā)者開放使用
2)SDK流量電量消耗很少
3)集成簡單,很快就能夠集成跑起來
4)服務(wù)器端推送支持大并發(fā)量逗柴、延遲小
友盟推送:
1.推送形式多樣:開發(fā)者可以在網(wǎng)頁設(shè)置或者采用API接入方式進(jìn)行消息推送蛹头,并可以選擇文本消息顿肺、應(yīng)用更新以及json式消息戏溺,滿足開發(fā)者不同場景下的運(yùn)營需求。
2.用戶分組靈活:開發(fā)者可以使用多個(gè)預(yù)置條件或者自定義的用戶標(biāo)簽把用戶分組屠尊,對每個(gè)分組的用戶推送更有針對性的消息旷祸,滿足開發(fā)者定向推送的需求。
3.設(shè)備能耗極低:SDK中采用了先進(jìn)的長鏈接多路復(fù)用以及其他優(yōu)化方案讼昆,將用戶設(shè)備的電量和流量消耗控制在最低水平托享,確保用戶體驗(yàn)最優(yōu)。
4.建立與用戶直接溝通的通道:不論是新品上架還是精彩活動(dòng)舉行浸赫,都可以實(shí)時(shí)的推送到用戶設(shè)備闰围,讓用戶第一時(shí)間獲取到相關(guān)信息。適時(shí)而準(zhǔn)確的消息推送既峡,可以大幅度提升用戶的活躍度和忠誠度羡榴。
功能特色
用戶分群推送
開發(fā)者可以使用多個(gè)預(yù)置條件或者自定義的用戶標(biāo)簽把用戶分群,對每個(gè)用戶群的用戶推送更有針對性的消息运敢,滿足開發(fā)者定向推送的需求校仑。
接入方式靈活
開發(fā)者可以通過網(wǎng)站W(wǎng)EB界面或者API接入方式進(jìn)行消息推送,且支持開發(fā)者提交已分群的用戶ID到友盟服務(wù)器進(jìn)行消息推送传惠,滿足開發(fā)者不同場景下的運(yùn)營需求迄沫。
服務(wù)質(zhì)量高
實(shí)現(xiàn)了同一設(shè)備多應(yīng)用共享一個(gè)長連接、智能心跳等優(yōu)化方案卦方。消息發(fā)送速度快羊瘩,長連接穩(wěn)定,設(shè)備能耗低。
優(yōu)點(diǎn):
友盟推送的SDK包很小困后,集成的時(shí)候不需要導(dǎo)入其它庫乐纸,集成后對應(yīng)用影響很小,使用方便摇予;
在網(wǎng)站的應(yīng)用信息中汽绢,可以看到推送的歷史記錄:包括發(fā)送總數(shù)、用戶打開數(shù)侧戴、打開率等等宁昭,方便統(tǒng)計(jì)
友盟推送集成是最簡單,使用也最方便酗宋,推送的渠道也是多樣的积仗。
缺點(diǎn):
但是在同網(wǎng)絡(luò)環(huán)境下,友盟的推送速度卻是比不上極光推送的蜕猫。而服務(wù)器端的api使用不太方便寂曹,需要設(shè)置一個(gè)服務(wù)器IP地址才能使用。自定義的字?jǐn)?shù)最多只有1500字
百度推送:
1.Push 服務(wù)
Push 服務(wù)初始化及綁定
Push 服務(wù)解除綁定
2.Tag 管理
創(chuàng)建 tag
刪除 tag
列出 tag
3.通知推送
4.推送效果反饋
百度有延遲回右,推送不穩(wěn)定隆圆,不人性化,很多也只是為了服務(wù)百度系的公司來用翔烁。到達(dá)率存在問題渺氧。開發(fā)者網(wǎng)站不是非常用戶友好。
百度推送蹬屹,推送Android還行侣背,在推送ios時(shí)推送內(nèi)容有限制,官方說是不能大于4k慨默,但是實(shí)際推送的內(nèi)容80個(gè)漢字以上就不行贩耐,推送不了。
優(yōu)點(diǎn):
1.1厦取、 推送及時(shí)潮太,支持推送通知、穿透消息推送蒜胖、富媒體消息推送消别。
1.2、 提供常見問題解答台谢。
1.3寻狂、 提供客服支持。
缺點(diǎn):
1.1朋沮、 與其他推送平臺(tái)相比官網(wǎng)沒有詳細(xì)的開發(fā)文檔蛇券,不方便開發(fā)者查閱缀壤。
1.2、 與其他推送平臺(tái)相比纠亚,集成困難塘慕。
建議:在官網(wǎng)放一份詳細(xì)的開發(fā)文檔,方便開發(fā)者查閱和集成蒂胞。
iOS推送簡介:
在移動(dòng)應(yīng)用中图呢,推送已經(jīng)成為不可缺少的重要功能。本文檔主要介紹有關(guān) iOS 推送的基礎(chǔ)知識(shí)骗随,并從幾個(gè)典型問題出發(fā)蛤织,分析如何解決在實(shí)現(xiàn)推送中出現(xiàn)的一些問題。
1.1 本地通知和遠(yuǎn)程通知簡介
在 iOS 設(shè)備上(模擬器無法使用推送)鸿染,系統(tǒng)收到通知后這樣處理:
在屏幕上彈出一些選項(xiàng)指蚜,或者在屏幕頂部顯示橫幅(banner)如下圖左
App 的角標(biāo)數(shù)值發(fā)生變化,具體表現(xiàn)為 App icon 右上角的小紅點(diǎn)及數(shù)字涨椒,如郵件中的紅點(diǎn)
伴隨推送消息的提示聲音
當(dāng)應(yīng)用處于前臺(tái)運(yùn)行時(shí)摊鸡,系統(tǒng)是不會(huì)在屏幕上顯示通知,但是仍會(huì)調(diào)用相應(yīng)的 API蚕冬。
只有真機(jī)可以使用推送功能免猾。
用戶可以設(shè)置每一個(gè) App 的通知權(quán)限,如下圖最后一個(gè):
用戶可以選擇關(guān)閉某個(gè)應(yīng)用的推送功能播瞳。還可以設(shè)置通知是否在通知中心顯示掸刊、通知到達(dá)時(shí)是否發(fā)出聲音免糕、通知能否改變 App 角標(biāo)以及鎖屏?xí)r是否顯示該 App 的通知赢乓,還可以設(shè)置通知到達(dá)時(shí)的提醒樣式。當(dāng)然石窑,這些都可以分別對每一個(gè)應(yīng)用進(jìn)行單獨(dú)設(shè)置牌芋。
1.1.1 本地通知
本地通知是一種基于時(shí)間的提醒方式。
本地通知最多向系統(tǒng)注冊 64 個(gè)松逊,當(dāng)超過這個(gè)數(shù)量后躺屁,最早注冊的本地通知會(huì)被丟棄。
本地通知在 iOS 設(shè)備上的顯示與遠(yuǎn)程推送通知一樣经宏。
1.1.2 遠(yuǎn)程通知
iOS App 運(yùn)行在后臺(tái)時(shí)犀暑,無法主動(dòng)進(jìn)行網(wǎng)絡(luò)連接。
遠(yuǎn)程通知可以用來提醒用戶烁兰。發(fā)送遠(yuǎn)程通知時(shí)耐亏,服務(wù)器首先需要使用推送證書與 APNs(Apple Push Notification service)建立安全連接,然后將消息傳遞給它沪斟。當(dāng) APNs 收到消息后广辰,會(huì)通過與手機(jī)之間的長連接下發(fā)到對應(yīng)的手機(jī)上,然后 iOS 彈出這條消息來提醒用戶。
用戶看通過點(diǎn)擊或滑動(dòng)通知來運(yùn)行 App择吊±罡可通過程序中相應(yīng)的方法可以獲取通知信息,然后做相應(yīng)的邏輯處理几睛。
如果不是通過通知啟動(dòng) App房轿,那么無法在程序中獲取通知信息。例如通過點(diǎn)擊應(yīng)用圖標(biāo)啟動(dòng) App所森。
推送通知都包含 Payload:一個(gè) Apple 已經(jīng)定義好的屬性列表冀续,操作系統(tǒng)根據(jù)它決定使用哪一種方式來提醒用戶。還可以在 Payload 中加入一些自定義數(shù)據(jù)必峰。
通知并不能一定到達(dá)洪唐。如果在用戶無法收到推送通知時(shí)(關(guān)機(jī)或網(wǎng)絡(luò)不可用),這種情況下 APNs 收到了多條發(fā)往這臺(tái)設(shè)備的通知吼蚁,那么只會(huì)保留最后一條凭需,最早的會(huì)被丟棄。
APNs 首先通過移動(dòng)蜂窩網(wǎng)絡(luò)發(fā)送通知肝匆,只有當(dāng)移動(dòng)蜂窩網(wǎng)絡(luò)不可用時(shí)才使用 Wi-Fi粒蜈。
1.2 通知的兩種推送環(huán)境
在使用 iOS 遠(yuǎn)程推送功能時(shí),有兩種不同的環(huán)境旗国。開發(fā)環(huán)境(Development)以及生產(chǎn)環(huán)境(Production)枯怖。
App 當(dāng)前使用的推送環(huán)境與 Xcode - Build Settings - Code Signing - Provisioning Profile 文件的模式一致。
1.2.1 證書與證書校驗(yàn)
與 APNs 之間是加密的連接能曾,因此需要使用證書來加密連接度硝。每個(gè)的推送環(huán)境有自己單獨(dú)的推送證書,即開發(fā)證書和生產(chǎn)證書寿冕。
在將證書最終轉(zhuǎn)為 pem 格式后蕊程,可通過與 APNs 連接來測試證書是否有效。
開發(fā)環(huán)境:
openssl s_client -connectgateway.sandbox.push.apple.com:2195-cert MyApnsDev.pem
生產(chǎn)環(huán)境:
openssl s_client -connectgateway.push.apple.com:2195-cert MyApnsPro.pem
當(dāng)輸入完命令回車后驼唱,終端首先會(huì)輸出很多相關(guān)信息藻茂。
當(dāng)連接建立失敗時(shí),會(huì)直接 close 掉玫恳。
當(dāng)連接建立成功時(shí)辨赐,終端會(huì)停止輸出,并等待你輸入京办,你可以隨便輸入一些字符后摁回車掀序,然后連接才會(huì)關(guān)閉。
以上命令在 Mac 下沒有問題臂港,在其他操作系統(tǒng)下需要指定服務(wù)器當(dāng)前的 CA 根證書森枪,具體可以從網(wǎng)站上下載:
下載完成之后视搏,在以上命令后面加上 -CAfile entrust2048ca.cer 即可
1.2.2 DeviceToken
通知需推送到具體某一臺(tái)設(shè)備,而 DeviceToken 就是這臺(tái)設(shè)備的標(biāo)識(shí)符县袱。在向 APNs 發(fā)送推送通知時(shí)浑娜,需要使用 DeviceToken 來指定這條通知將要到達(dá)的設(shè)備 。
每一臺(tái)設(shè)備式散,不同的推送環(huán)境下分別有一個(gè) DeviceToken筋遭。即 DeviceToken 也分開發(fā)環(huán)境和生產(chǎn)環(huán)境。
應(yīng)用在向 APNs 注冊推送通知時(shí)暴拄,會(huì)根據(jù)當(dāng)前 Xcode 工程中 target 對應(yīng)的 Provisioning Profile 決定請求對應(yīng)環(huán)境的 DeviceToken漓滔。即系統(tǒng)返回的 DeviceToken 其環(huán)境與 Provisioning Profile 的環(huán)境對應(yīng)。
一般在使用 Xcode 開發(fā)時(shí)乖篷,Provisioning Profile 為 Development 响驴,因此獲取的 DeviceToken 也是開發(fā)模式。
在 App 需要打包為 ipa 文件或者需要上傳到 AppStore 時(shí)撕蔼,會(huì)將 Provisioning Profile 文件修改為 Distribution豁鲤,這時(shí)獲取到的 DeviceToken 是生產(chǎn)模式。
1.3 在應(yīng)用程序中注冊遠(yuǎn)程推送功能
App 必須要向 APNs 請求注冊以實(shí)現(xiàn)推送功能鲸沮,在請求成功后琳骡,APNs 會(huì)返回一個(gè)設(shè)備的標(biāo)識(shí)符即 DeviceToken 給 App,服務(wù)器在推送通知的時(shí)候需要指定推送通知目的設(shè)備的 DeviceToken讼溺。在 iOS 8 以及之后楣号,注冊推送服務(wù)主要分為四個(gè)步驟:
使用registerUserNotificationSettings:注冊應(yīng)用程序想要支持的推送類型
通過調(diào)用registerForRemoteNotifications方法向 APNs 注冊推送功能
請求成功時(shí),系統(tǒng)會(huì)在應(yīng)用程序委托方法中返回 DeviceToken怒坯,請求失敗時(shí)炫狱,也會(huì)在對應(yīng)的委托方法中給出請求失敗的原因。
將 DeviceToken 上傳到服務(wù)器敬肚,服務(wù)器在推送時(shí)使用毕荐。
上述第一個(gè)步驟注冊的 API 是 iOS 8 新增的束析,因此在 iOS 7艳馒,前兩個(gè)步驟需更改為 iOS 7 中的 API。
DeviceToken 有可能會(huì)更改员寇,因此需要在程序每次啟動(dòng)時(shí)都去注冊并且上傳到你的服務(wù)器端弄慰。
注意:iOS 設(shè)備與 APNs 需要建立一條長連接,之后的推送注冊以及推送獲取都需要通過這條長連接蝶锋。
當(dāng) iOS 設(shè)備無網(wǎng)絡(luò)可用時(shí)陆爽,在向 APNs 請求注冊后,既不會(huì)有注冊成功的回調(diào)扳缕,也不會(huì)有注冊失敗的回調(diào)慌闭。如果發(fā)生這種情況别威,需要檢查設(shè)備的網(wǎng)絡(luò)連接。
開發(fā)環(huán)境和生產(chǎn)環(huán)境建立不同的長連接驴剔,且設(shè)備上要至少有一個(gè)開發(fā)環(huán)境的 App 并且注冊推送省古,才會(huì)建立開發(fā)環(huán)境下的長連接。
當(dāng)已經(jīng)注冊過推送服務(wù)后丧失,以后系統(tǒng)會(huì)立刻返回給你 DeviceToken豺妓。還有一點(diǎn)是,返回 DeviceToken 的回調(diào)方法并不一定是只有在你注冊或者再次注冊時(shí)才被系統(tǒng)調(diào)用布讹,當(dāng)DeviceToken 改變時(shí)也會(huì)被系統(tǒng)直接調(diào)用琳拭。
1.4 在程序中處理通知
我們來看一下當(dāng)系統(tǒng)傳遞本地或遠(yuǎn)程通知的時(shí)候都有哪些情況。
通知到達(dá)時(shí)描验,應(yīng)用不在前臺(tái)白嘁。
這種情況下,操作系統(tǒng)將呈現(xiàn)通知膘流,彈出一個(gè)選項(xiàng)或者在屏幕上部顯示 banner 提醒权薯,給 App 角標(biāo)設(shè)置對應(yīng)的數(shù)字,可能播放提示音睡扬,當(dāng)用戶稍微往下滑動(dòng)通知時(shí)顯示更多的 action 按鈕(如果有設(shè)置)盟蚣。
通知到達(dá)時(shí),應(yīng)用在前臺(tái)運(yùn)行卖怜。
這種情況下屎开,不會(huì)彈出 banner。系統(tǒng)會(huì)根據(jù)當(dāng)前的通知是本地通知還是遠(yuǎn)程通知马靠,調(diào)用不同的方法奄抽,并且在方法中傳遞通知的 Payload 數(shù)據(jù)。
在 iOS8 的通知中甩鳄,用戶點(diǎn)擊通知上的自定義 action 按鈕進(jìn)入應(yīng)用逞度。
這種情況下,系統(tǒng)會(huì)調(diào)用 iOS8 中對 action 按鈕新增的處理方法妙啃。
用戶點(diǎn)擊通知進(jìn)入應(yīng)用档泽。
系統(tǒng)會(huì)根據(jù)當(dāng)前的通知是本地通知還是遠(yuǎn)程通知,調(diào)用不同的方法揖赴,并且在方法中傳遞通知的 Payload 數(shù)據(jù)馆匿。
注意:只有當(dāng)通過通知進(jìn)入到 App 時(shí),才可以獲取到通知信息燥滑。
1.4.1 自定義通知提示音
你可以在 App 的 Bundle 中加入一段自定義提示音文件渐北。然后當(dāng)通知到達(dá)時(shí)可以指定播放這個(gè)文件。必須為以下幾種數(shù)據(jù)格式:
Linear PCM
MA4(IMA/ADPCM)
μLaw
aLaw
你可以將它們打包為aiff铭拧、wav或caf文件赃蛛。自定義的聲音文件時(shí)間必須小于 30 秒恃锉,如果超過了這個(gè)時(shí)間,將被系統(tǒng)聲音代替呕臂。
1.4.2 Payload
Payload 是通知的一部分淡喜,每一條推送通知都包含一個(gè) Payload。它包含了系統(tǒng)提醒用戶通知到達(dá)的方式诵闭,還可以添加自定義的數(shù)據(jù)炼团。即通知主要傳遞的數(shù)據(jù)為 Payload。
Payload 本身為 JSON 格式的字符串疏尿,它內(nèi)部必須要包含一個(gè)鍵為aps的字典瘟芝。aps 中可以包含以下字段中的一個(gè)或多個(gè):
alert:其內(nèi)容可以為字符串或者字典,如果是字符串褥琐,那么將會(huì)在通知中顯示這條內(nèi)容
badge:其值為數(shù)字锌俱,表示當(dāng)通知到達(dá)設(shè)備時(shí),應(yīng)用的角標(biāo)變?yōu)槎嗌俚谐省H绻麤]有使用這個(gè)字段贸宏,那么應(yīng)用的角標(biāo)將不會(huì)改變。設(shè)置為 0 時(shí)磕洪,會(huì)清除應(yīng)用的角標(biāo)吭练。
sound:指定通知展現(xiàn)時(shí)伴隨的提醒音文件名。如果找不到指定的文件或者值為 default析显,那么默認(rèn)的系統(tǒng)音將會(huì)被使用鲫咽。如果為空,那么將沒有聲音谷异。
content-available:此字段為 iOS 7 silent remote notification 使用分尸。不使用此功能時(shí)無需包含此字段。
推送通知跟NSNotification有所區(qū)別:
1> NSNotification是抽象的歹嘹,不可見的
2> 推送通知是可見的(能用肉眼看到)
iOS中提供了2種推送通知: 本地推送通知, 遠(yuǎn)程推送通知
1> 本地推送通知(Local Notification)
2> 遠(yuǎn)程推送通知(Remote Notification)
推送通知可以不讓在前臺(tái)運(yùn)行的app,告知app內(nèi)部發(fā)生了什么變化,比如:有新的內(nèi)容,新消息等.
推送通知的使用:
發(fā)出推送通知時(shí)箩绍,如果當(dāng)前程序正運(yùn)行在前臺(tái),那么推送通知就不會(huì)被呈現(xiàn)出來
點(diǎn)擊推送通知后尺上,默認(rèn)會(huì)自動(dòng)打開發(fā)出推送通知的app
不管app打開還是關(guān)閉材蛛,推送通知都能如期發(fā)出
推送通知有5種呈現(xiàn)效果:
1. 在屏幕頂部顯示一塊橫幅(顯示具體內(nèi)容)
2. 在屏幕中間彈出一個(gè)UIAlertView(顯示具體內(nèi)容,使用較少)
3. 在鎖屏界面顯示一塊橫幅(鎖屏狀態(tài)下,顯示具體內(nèi)容)
4. 播放音效(提醒作用)
5. 更新app圖標(biāo)的數(shù)字(說明新內(nèi)容的數(shù)量)
推送通知分為本地推送通知和遠(yuǎn)程推送通知,下面一一介紹.
本地推送通知
本地推送通知不需要服務(wù)器的支持,不需要聯(lián)網(wǎng)就可以發(fā)送通知.通常本地推送通知用于定時(shí)提醒用戶,比如清理垃圾,淘寶購物,紀(jì)念日提醒等任務(wù).
在蘋果官方給出了本地推送通知的一些屬性,以及使用.
屬性介紹:
@property(nonatomic,copy)NSDate *fireDate;// 設(shè)置本地推送的時(shí)間@property(nonatomic,copy) NSTimeZone *timeZone;// 時(shí)區(qū)(一般設(shè)置為[NSTimeZone defaultTimeZone] 尖昏,跟隨手機(jī)的時(shí)區(qū))@property(nonatomic) NSCalendarUnit repeatInterval;// 沒隔多久重復(fù)發(fā)出一次@property(nonatomic,copy)NSCalendar *repeatCalendar;// 設(shè)置日期@property(nonatomic,copy) CLRegion *region NS_AVAILABLE_IOS(8_0);// 比如某一個(gè)區(qū)域的時(shí)候發(fā)出通知@property(nonatomic,assign)BOOL regionTriggersOnce NS_AVAILABLE_IOS(8_0);// 進(jìn)入?yún)^(qū)域是否重復(fù)@property(nonatomic,copy)NSDictionary *userInfo;// 附加的額外信息@property(nonatomic,copy)NSString *alertBody;// 消息的內(nèi)容@property(nonatomic)BOOL hasAction;// 是否顯示alertAction的文字(默認(rèn)是YES)@property(nonatomic,copy)NSString *alertAction;// 設(shè)置鎖屏狀態(tài)下,顯示的一個(gè)文字@property(nonatomic,copy)NSString *alertLaunchImage;// 啟動(dòng)圖片@property(nonatomic,copy)NSString *soundName;//? UILocalNotificationDefaultSoundName@property(nonatomic)NSInteger applicationIconBadgeNumber;// 應(yīng)用圖標(biāo)右上角的提醒數(shù)字@property(nonatomic,copy)NSArray *scheduledLocalNotifications;// 獲得被調(diào)度(定制)的所有本地推送通知(已經(jīng)發(fā)出且過期的推送通知就算調(diào)度結(jié)束仰税,會(huì)自動(dòng)從這個(gè)數(shù)組中移除)
使用方法:
創(chuàng)建本地通知
UILocalNotification *localNoti = [[UILocalNotification alloc] init];
調(diào)度本地推送通知(調(diào)度完畢后,推送通知會(huì)在特地時(shí)間fireDate發(fā)出)
[[UIApplication sharedApplication]scheduleLocalNotification:localNoti];取消調(diào)度本地推送通知
-(void)cancelLocalNotification:(UILocalNotification *)notification;-(void)cancelAllLocalNotifications;
立即發(fā)出本地推送通知
-(void)presentLocalNotificationNow:(UILocalNotification *)notification;
注意:
iOS8.0以后在本地推送通知上新加了一些新功能,為了用戶體驗(yàn),以及更加人性化,如果要使用本地通知抽诉,需要得到用戶的許可.
需要在AppDelegate中添加如下代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {/*? ?? UIUserNotificationTypeNone? ? = 0,? ? ? 沒有,沒有本地通知? ?? UIUserNotificationTypeBadge?? = 1 << 0, 接受圖標(biāo)右上角提醒數(shù)字? ?? UIUserNotificationTypeSound?? = 1 << 1, 接受通知時(shí)候,可以發(fā)出音效? ?? UIUserNotificationTypeAlert?? = 1 << 2, 接受提醒(橫幅/彈窗)? ?? */// iOS8需要添加請求用戶的授權(quán)if ([UIDevice currentDevice].systemVersion.floatValue >=8.0) {? ? ? ? UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}
}
點(diǎn)擊本地推送通知
當(dāng)用戶點(diǎn)擊本地推送通知,會(huì)自動(dòng)打開app吐绵,這里有2種情況
1> app并沒有關(guān)閉迹淌,一直隱藏在后臺(tái)(運(yùn)行在后臺(tái))
讓app進(jìn)入前臺(tái)河绽,并會(huì)調(diào)用AppDelegate的下面方法(并非重新啟動(dòng)app)
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
1
1
2> app已經(jīng)被關(guān)閉(進(jìn)程已死)
啟動(dòng)app,啟動(dòng)完畢會(huì)調(diào)用AppDelegate的下面方法
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
launchOptions參數(shù)通過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象
若要實(shí)現(xiàn)界面的跳轉(zhuǎn),需要分清當(dāng)前應(yīng)用程序的所處狀態(tài),進(jìn)行判斷:
1> 若是當(dāng)前應(yīng)用在后臺(tái)運(yùn)行,接收到通知時(shí),要想進(jìn)行界面的跳轉(zhuǎn),可以在didReceiveLocalNotification:方法中實(shí)現(xiàn)跳轉(zhuǎn)界面的方法
2> 若是當(dāng)前的應(yīng)用程序已經(jīng)關(guān)閉,我們在前面說到,當(dāng)應(yīng)用關(guān)閉,推送通知也會(huì)如期發(fā)送.但此時(shí),是不會(huì)走didReceiveLocalNotification:方法的,那我們只有didFinishLaunchingWithOptions:方法利用,launchOptions參數(shù)通過UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知對象,實(shí)現(xiàn)跳轉(zhuǎn)的功能.
下面是演示代碼:
#import"AppDelegate.h"@interfaceAppDelegate ()@end@implementationAppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {/*? ?? UIUserNotificationTypeNone? ? = 0,? ? ? 沒有,沒有本地通知? ?? UIUserNotificationTypeBadge?? = 1 << 0, 接受圖標(biāo)右上角提醒數(shù)字? ?? UIUserNotificationTypeSound?? = 1 << 1, 接受通知時(shí)候,可以發(fā)出音效? ?? UIUserNotificationTypeAlert?? = 1 << 2, 接受提醒(橫幅/彈窗)? ?? */// iOS8需要添加請求用戶的授權(quán)if ([UIDevice currentDevice].systemVersion.floatValue >=8.0) {? ? ? ? UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];? ? ? ? [application registerUserNotificationSettings:settings];? ? }if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {// 跳轉(zhuǎn)界面? ? }returnYES;}/** *? 如果應(yīng)用在后臺(tái),通過點(diǎn)擊通知的時(shí)候打開應(yīng)用會(huì)來到該代理方法 *? 如果應(yīng)用在前臺(tái),接受到本地通知就會(huì)調(diào)用該方法 * *? @param notification 通過哪一個(gè)通知來這里 */- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{if (application.applicationState == UIApplicationStateActive)return;if (application.applicationState == UIApplicationStateInactive) {// 實(shí)現(xiàn)跳轉(zhuǎn)? ? }}- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{returnYES;}#import"ViewController.h"
@interfaceViewController ()// 點(diǎn)擊按鈕之后添加通知- (IBAction)addLocalNote;@end@implementationViewController- (void)viewDidLoad {? ? [super viewDidLoad];? ? [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];}- (IBAction)addLocalNote {// 1.創(chuàng)建本地通知UILocalNotification *localNote = [[UILocalNotification alloc] init];// 設(shè)置什么時(shí)間彈出? ? localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];// 設(shè)置彈出的內(nèi)容? ? localNote.alertBody = @"您有新消息";// 設(shè)置鎖屏狀態(tài)下,顯示的一個(gè)文字? ? localNote.alertAction = @"快點(diǎn)打開";// 是否顯示alertAction的文字(默認(rèn)是YES)? ? localNote.hasAction =YES;// 設(shè)置音效? ? localNote.soundName = UILocalNotificationDefaultSoundName;// 應(yīng)用圖標(biāo)右上角的提醒數(shù)字? ? localNote.applicationIconBadgeNumber =1;// 設(shè)置UserInfo來傳遞信息? ? localNote.userInfo = @{@"alertBody" : localNote.alertBody, @"applicationIconBadgeNumber" : @(localNote.applicationIconBadgeNumber)};// 2.調(diào)度通知? ? [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
遠(yuǎn)程推送通知
遠(yuǎn)程推送通知:就是通過網(wǎng)絡(luò)從遠(yuǎn)程服務(wù)器推送給客戶端的通知.
為什么需要遠(yuǎn)程推送通知唉窃?
傳統(tǒng)獲取數(shù)據(jù)的局限性
只要用戶關(guān)閉了app耙饰,就無法跟app的服務(wù)器溝通,無法從服務(wù)器上獲得最新的數(shù)據(jù)內(nèi)容
遠(yuǎn)程推送通知可以解決以上問題
不管用戶打開還是關(guān)閉app纹份,只要聯(lián)網(wǎng)了苟跪,都能接收到服務(wù)器推送的遠(yuǎn)程通知
遠(yuǎn)程推送通知的使用
所有的蘋果設(shè)備,在聯(lián)網(wǎng)狀態(tài)下蔓涧,都會(huì)與蘋果的服務(wù)器建立長連接
長連接: 只要聯(lián)網(wǎng)了件已,就一直建立連接
長連接的作用: 時(shí)間校準(zhǔn), 系統(tǒng)升級(jí), 查找我的iPhone
長連接的好處 : 數(shù)據(jù)傳輸速度快 , 數(shù)據(jù)保持最新狀態(tài)
遠(yuǎn)程推送功能機(jī)制
蘋果給iOS和Mac添加了消息推送的功能,使得我們可以通過后臺(tái)服務(wù)器給應(yīng)用程序(APP)發(fā)送消息元暴,不管APP是否正在使用篷扩,比如郵箱的來件提示功能。這項(xiàng)服務(wù)被稱為Apple Push Notification service(APNs)茉盏。里面一共涉及到四個(gè)角色:APP鉴未、設(shè)備、APNs和應(yīng)用后臺(tái)服務(wù)器(Provider)鸠姨,其中APP铜秆、后臺(tái)服務(wù)器和APNs之間使用deviceToken唯一的標(biāo)識(shí)一個(gè)用戶。
推送服務(wù)的工作流程:
APP向系統(tǒng)注冊推送服務(wù)讶迁。
設(shè)備從APNs請求deviceToken羽峰。
通過代理方法將deviceToken返回給APP。
APP將deviceToken發(fā)送給應(yīng)用后臺(tái)服務(wù)器(Provider)添瓷。
應(yīng)用后臺(tái)服務(wù)器保存deviceToken梅屉,然后在需要推送通知的時(shí)候,給APNs發(fā)送信息鳞贷,使用deviceToken標(biāo)識(shí)所要送達(dá)的客戶端坯汤。
APNs將后臺(tái)服務(wù)器發(fā)過來的數(shù)據(jù)推送到設(shè)備。
設(shè)備將消息分發(fā)給應(yīng)用程序搀愧。
在使用推送功能的時(shí)候惰聂,需要在開發(fā)者中心創(chuàng)建支持Push Notification的證書,并且將證書和私鑰用于應(yīng)用后臺(tái)服務(wù)器與APNs之間通信咱筛。
我也寫了一個(gè)比較易懂的遠(yuǎn)程推送流程圖!http://blog.csdn.net/ismilesky/article/details/48324723
遠(yuǎn)程推送近年來,都是通過第三方進(jìn)行實(shí)現(xiàn),因?yàn)榈谌酵扑偷墓δ鼙容^強(qiáng)大.
推送平臺(tái): 百度推送 , 極光推送, 騰訊信鴿推送, 個(gè)推
遠(yuǎn)程推送我們這里以極光推送(第三方)為例,進(jìn)行測試.
極光遠(yuǎn)程推送的使用
如要使用極光第三方遠(yuǎn)程推送,我們需要集成iOS SDK,需要進(jìn)行應(yīng)用的配置,和環(huán)境配置.在開發(fā)者中心有
developer.apple.com開發(fā)者賬號(hào) , iOS真機(jī)(iPhone搓幌、iPad、iPod)等迅箩。
遠(yuǎn)程推送應(yīng)用配置過程:
創(chuàng)建支持遠(yuǎn)程推送功能的App ID
申請開發(fā)者證書溉愁,并選中剛剛創(chuàng)建的App ID
下載CER文件,并導(dǎo)入鑰匙串管理
申請發(fā)布證書饲趋,并選中剛剛創(chuàng)建的App ID
下載CER文件拐揭,并導(dǎo)入鑰匙串管理
檢查App ID撤蟆,確認(rèn)證書已經(jīng)指定
這些相關(guān)配置極光推送已經(jīng)給了非常詳細(xì)的文檔資料, iOS SDK集成指南 :http://docs.jpush.io/guideline/ios_guide/, iOS SDK調(diào)試指南 :http://docs.jpush.io/client/ios_tutorials/#ios-sdk, 只需要按照流程進(jìn)行就可以.
實(shí)現(xiàn)代碼:
#define kDeviceVersion? ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
#import"AppDelegate.h"
#import"APService.h"
@interface AppDelegate ()
@end
@implementationAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (kDeviceVersion) {
//可以添加自定義categories??
? ? ? [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound |UIUserNotificationTypeAlert) categories:nil];??
? }
else {
//categories 必須為nil? ? ? ??
[APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil];? ?
?}
#else//categories 必須為nil?
?? [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil];
#end
if? ? [APService setupWithOption:launchOptions]; return YES;
}
#pragma mark - 獲取device token (必須實(shí)現(xiàn))// 當(dāng)?shù)玫教O果的APNs服務(wù)器返回的DeviceToken就會(huì)被調(diào)用
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{NSLog(@"%@",deviceToken);
// Required? ? [APService registerDeviceToken:deviceToken];}#pragma mark - 獲取device token失敗
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{NSLog(@"function == %s? line == %d? error == %@",__FUNCTION__,__LINE__,error);}
// 接收到遠(yuǎn)程通知,觸發(fā)方法和本地通知一致 (必須實(shí)現(xiàn))
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {// Required??
? [APService handleRemoteNotification:userInfo];
}
#pragma mark - 使用后臺(tái)的遠(yuǎn)程消息推送 (必須實(shí)現(xiàn))/**?
1> 在Capabilities中打開遠(yuǎn)程推送通知
?2> 實(shí)現(xiàn)該代理方法遠(yuǎn)程消息數(shù)據(jù)格式: {"aps" : {"content-available" : 1},"content-id" : 42} 執(zhí)行completionHandler有兩個(gè)目的
?1> 系統(tǒng)會(huì)估量App消耗的電量堂污,并根據(jù)傳遞的UIBackgroundFetchResult 參數(shù)記錄新數(shù)據(jù)是否可用?
2> 調(diào)用完成的處理代碼時(shí)家肯,應(yīng)用的界面縮略圖會(huì)自動(dòng)更新 注意:接收到遠(yuǎn)程通知到執(zhí)行完網(wǎng)絡(luò)請求之間的時(shí)間不能超過30秒?
if (userInfo) {
?int contentId = [userInfo[@"content-id"] intValue];?
ViewController *vc = (ViewController *)application.keyWindow.rootViewController;?
[vc loadDataWithContentID:contentId completion:^(NSArray *dataList) {?
vc.dataList = dataList; NSLog(@"刷新數(shù)據(jù)結(jié)束");?
completionHandler(UIBackgroundFetchResultNewData); }];?
} else {?
completionHandler(UIBackgroundFetchResultNoData);?
}*/
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
?{// IOS 7 Support Required?
?? [APService handleRemoteNotification:userInfo];?
?? [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];
// 判斷應(yīng)用程序在前臺(tái)還是后臺(tái)
if (application.applicationState == UIApplicationStateActive)
?{// 活躍狀態(tài)// 實(shí)現(xiàn)方法? ?
?}
else if (application.applicationState == UIApplicationStateInactive)
?{// 不活躍狀態(tài)// 實(shí)現(xiàn)方法? ??
}else {
// application.applicationState == UIApplicationStateBackground
// 后臺(tái)// 實(shí)現(xiàn)方法??
? }
/** 必須回調(diào) */?
?? completionHandler(UIBackgroundFetchResultNewData);
}
測試時(shí),運(yùn)行完應(yīng)用程序,要發(fā)送通知,進(jìn)行推送的測試,真機(jī)收到通知才算成功.