iOS客户端如何测试推送
????當我們在客戶端實現推送跳轉需求后,但是服務器還沒有做好后臺的配置,此時需要測試收到推送消息之后能否按照預期,執行我們的代碼。但在這個情況下如何去做呢。這里可以提供給大家兩個選擇。
?????1. 封裝好處理邏輯的接口,在程序啟動或者某個時刻模擬數據,直接調用處理邏輯的接口,查看是否符合預期。該情況只適用于測試跳轉邏輯,不能測試數據解析的正確性(例如字段名是否正確、字段的類型是否正確等)。
????例如,我們處理推送消息的函數都寫在了Appdelegate.m中的- (void)dealWithNotification:(NSDictionary*)userInfo函數里
????那么我們就需要來構造數據進行模擬推送,比如這樣:
????????//? 用于模擬器測試推送 方便快速測試推送問題 使用這個函數測試完,請務必在真實推送情況下測試
????????- (void)sendNotificationSelf:(RemoteNotificationType)type
????????{
? ? ????????NSDictionary * dictionary = nil;
? ? ????????if (type == kRemoteNotificationExpression)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(3), @"flag", @(1033), @"secondClassifyId", nil];
? ? ????????else if (type == kRemoteNotificationDwaft)
? ? ? ????? ????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(5), @"flag", @"寶貝計劃", @"templateName", @(126), @"templateId", nil];
? ????????? else if (type == kRemoteNotificationCharacter)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(6), @"flag", nil];
? ? ????????else if (type == kRemoteNotificationSoundExpressionCategory)
? ? ? ????????? dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(8), @"flag", @(176), @"classifyId",? @"", @"classifyName", nil];
? ????????? else if (type == kRemoteNotificationSoundExpressionSubjectDetail)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(9), @"flag", @(18), @"subjectId", @"動物成精了", @"subjectName", nil];
? ? ????????else if (type == kRemoteNotificationMessageCenter)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(10), @"flag", nil];
? ? ????????else if (type == kRemoteNotificationFansList)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(11), @"flag", nil];
? ? ????????else if (type == kRemoteNotificationStatusDetail)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(12), @"flag", @"" , @"sid", nil];
? ????????? else if (type == kRemoteNotificationUserHomePage)
? ? ? ? ????????dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@(13), @"flag", [UserInfo getSelf].uid, @"uid", nil];
? ? ????????[self dealWithNotification:dictionary];
????????}
??? ????這段代碼的作用非常簡單,其實就是根據預設好的推送類型,來模擬不同的推送數據,進而調用推送函數的統一處理方法。
????????我們可以在應用啟動的時候調用來模擬應用未開啟時點擊推送的效果,在點擊某個按鈕時調用來模擬應用在前臺收到推送 ? ? ? ? 的效果,寫一個延時來調用然后點擊home鍵,來模擬應用在后臺收到推送的效果了。
????????怎么樣,看起來還不錯吧,基本上可以解決問題,那還有沒有更好的方案了,請繼續看。
????2. 既然服務器還沒有做好相關的配置,那么為什么我們自己做一個閹割版的服務器,只做推送測試呢?OK,那就了解一下,iOS推送通知的基本原理。
iOS推送通知的基本原理
????蘋果的推送服務是由自己專門的推送服務器APNs(Apple Push Notification service)來完成的,過程是APNs收到我們自己的應用服務器發出的被推送的消息,將這條消息推送到制定的iOS設備上,然后再由iOS設備通知到我們的應用程序,我們將會以通知或者聲音的形式收到推送回來的消息。iOS遠程推送的前提是,裝有我們應用程序的iOS設備,要向APNs服務器注冊,注冊成功后,APNs服務器將會給我們返回一個deviceToken,我們獲取到這個token后,將它發送給我們自己的應用服務器。當我們需要推送消息時,我們的應用服務器將消息按照指定的格式進行打包,然后結合iOS設備的deviceToken一起發給APNs服務器。iOS設備會和APNs服務器維持一個基于TCP的長連接,APNs服務器將新消息推送到iOS設備上,然后在設備屏幕上進行顯示。
????其實總結下來過程如下:
????1.????客戶端向APNs申請注冊消息推送服務。
????2.????APNs服務器接受到請求后,并將deviceToken返回給設備上的客戶端
????3.????客戶端將deviceToken發送給自己的后臺服務器,后臺接受后并儲存。
????4.????后臺服務器向APNs服務器發送推送消息
????5.????APNs服務器接受后,將消息發送給deviceToken對應的設備
????我們來看上面的過程中服務器要做的就是接受并儲存客戶端發送的deviceToken,以便之后再要發送推送時,與APNs發送推送消息。所以如果要哦讓我們自己做一個閹割版的服務端也很簡單,首先deviceToken,只要我們不卸載應用,那么他是不會變化的。所以我們只要在XCode中輸出deviceToken并且記錄下來就可以解決存儲的問題,那么后臺服務器怎么與APNs服務器交互的呢,其實只需要跟APNs進行SSL連接,把我們APNs預期的格式的數據傳遞過去就可以了?;贛ac平臺,我們可以選擇PHP來實現,畢竟Mac自帶了PHP環境,使用起來很方便(況且PHP是世界上最好的語言J)。
????使用PHP進行通信的話,就需要使用.pem文件。
.PEM文件是什么?
????如果把SSL系統比喻成工商局系統。
????首先有SSL就有CA,certificateauthority。證書局,同于制作、認證證書的第三方機構,我們假設應用執照非常難制作,就像身份證一樣,需要有制作公司來提供,并且提供技術幫助工商局驗證執照的真偽。
????然后CA是可以有很多的,也就是可以有多個制證公司,但是工商局只有一個,它來說哪個制證公司是可信的,哪些是假的,需要打擊。在SSL的世界中,微軟、谷歌和Mozilla扮演了一部分的這個角色。也就是說,IE、Chrome、Firefox中內置有一些CA,經過這些CA頒發,驗證過的證書都是可信的,否則就會提示你不安全。
????要開店的老板去申請營業執照的時候是需要提交他的身份證的,然后搬出來的營業執照有他的照片和名字。身份證相當于私鑰,營業執照就是證書,Ceritificate,.cer文件。
????然后私鑰和公鑰他們在數據加密層面,數據的流向是這樣的。
消息-->[公鑰]-->加密后的信息-->[私鑰]-->消息
????公鑰是可以隨便扔給別人的,他把消息加了密傳遞給我??梢赃@樣理解,我有一個箱子,一把鎖和一把鑰匙,我把箱子和開著的鎖給別人,他寫信放到箱子里面,鎖上,然后傳遞回我受傷的途中誰都是打不開箱子的,只有我可以用原來的鑰匙打開,這就是SSL,公鑰、私鑰傳遞加密消息的方式。這里的密鑰就是.key文件。
????PEM,它是由RFC1421至1424定義的一種數據格式。其實里面的.cert和.key文件都是PEM格式的,只不過在有些系統(比如Windows)里面會根據擴展名的不同而做不同的事情。所以當看到.pem文件時,它里面的內容可能是certificate也可能是key,也可能兩個都有,要看具體情況,可以通過OpenSSL查看。而在與APNs的通訊中,我們需要傳遞的是同時包含.cert和.key的文件。蘋果通過這個來確定你是否是開發者本人。
如何得到.pem文件
???1. 如果在Mac上鑰匙串訪問中能找到Apple Development iOS Push Server證書的話,可以在證書上面右鍵導出生成apns_dev_cert.p12。如果沒有的話,可以在蘋果開發者中心生成aps_development.cer文件,然后下載,雙擊導入鑰匙串。
????2. 然后在鑰匙串訪問中找到Apple DevelopmentiOS Push Server密鑰,右鍵生成apns_dev_key.p12。
????3. 打開終端,進入p12證書所在的目錄,輸入openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12 生成apns-dev-cert.pem
????4. 輸入openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12 生成apns-dev-key.pem,要輸入密碼,記住這個密碼
????5. 把兩個.pem文件合并?cat apns-dev-cert.pem apns-dev-key.pem > apns-dev.pem
????這樣就得到了開發環境的pem文件了,如果是生產環境,那么需要選擇生環境的證書并做相同的操作,得到apns-dis-cert.pem即可。
? ?可以通過?openssl s_client -connect?gateway.sandbox.push.apple.com:2195?-cert apns-dev-cert.pem -key apns-dev-key.pem?測試證書是否正常。執行完畢后,直接輸入任意字符,回車,出現closed,表示可用。否則打印錯誤信息。
? ?如果出現上面的錯誤信息,那么可能是OpenSSL的cert.pem文件問題,可以在終端中輸入命令php -r "print_r(openssl_get_cert_locations());"來查看default_cert_file的路徑,并且替換掉,可用版本的cert.pem在這里(鏈接:https://pan.baidu.com/s/1IlOqpWK-ugenEEjaWqNf9A? 密碼:7qmc),替換前打印下原文件的權限,替換后修改為同樣的權限即可。
編寫PHP
????.pem有了,那么我們需要做的就是編寫PHP了。直接送上源碼,需要注意的是修改pass變量為剛才生成.pem的密碼,替換deviceToken為測試設備的token。如果是在開發環境,那么選擇ssl://gateway.sandbox.push.apple.com:2195,如果是生產環境,那么選擇ssl://gateway.push.apple.com:2195。代碼如下:
<?php
$deviceToken= 'f020999681cc383f6a5e3efb8e3321912808ade966d20a3ec9696fbd5fa24e4c'; //沒有空格
$type = 1; // 1 配圖 2 逗圖工坊 3 文字表情
$body = 0;
if ($type == 1)
{
$body = array( "aps" =>array("alert" => '配圖推送測試',"badge" => 1,"sound"=>'default'),?
"flag" => "2",?
"imageListName" => "我快瘋了!",?
"imageListId" => 2589);? //推送方式,包含內容和聲音
}
elseif ($type == 2)
{
$body = array( "aps" => array("alert" => '逗圖工坊推送測試',"badge" => 1,"sound"=>'default'),?
"flag" => "5",?
"templateName" => "二次元",?
"templateId" => 477);? //推送方式,包含內容和聲音
}
elseif ($type == 3) {
$body = array( "aps" =>array("alert" => '文字表情推送測試',"badge" => 1,"sound"=>'default'),?
"flag" => "6");? //推送方式,包含內容和聲音
}
elseif ($type == 4)
{
$body = array( "aps" =>array("alert" => '表情推送測試',"badge" => 1,"sound"=>'default'),?
"flag" => "3",?
"secondClassifyName" => "斗圖應答",?
"secondClassifyId" => 1033);? //推送方式,包含內容和聲音
}
$ctx = stream_context_create();
//如果在Windows的服務器上,尋找pem路徑會有問題,路徑修改成這樣的方法:
//$pem = dirname(__FILE__) . '/' . 'apns-dev.pem';
//linux 的服務器直接寫pem的路徑即可
stream_context_set_option($ctx,"ssl","local_cert","apns-dev.pem");
$pass = "123456";
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);
$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);
?>
執行測試
最后把push.php和apns-dev.pem放到同一目錄下,進入命令行輸入php push.php即可。
參考文獻:
1.https://www.zhihu.com/question/29620953
2.http://blog.sina.com.cn/s/blog_6f9a9718010128hi.html
3.https://www.cnblogs.com/cocoajin/p/3470704.html
總結
以上是生活随笔為你收集整理的iOS客户端如何测试推送的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: systemd 服务使用
- 下一篇: 智能灯丝灯方案为复古设计注入“ 科技基因