iOS推送

1.推送過(guò)程簡(jiǎn)介

8325A44F-2047-44C1-8B0B-CFCA4DB2C2E4.png

< 1.iPhone向APNS索取DeviceToken
<2.APNS返回Token
<3.iPhone將獲取的Token上傳至App對(duì)應(yīng)的服務(wù)器
<4.服務(wù)器將Token和推送的要聞上傳至APNS
<5.APNS將消息推送給iPhone用戶

  1. 用到的證書(shū)文件及生成過(guò)程

    (1)certSigningRequest文件俏竞,該文件在MAC系統(tǒng)中生成梨熙,用于在Apple網(wǎng)站上申請(qǐng)推送證書(shū)文件杰扫。
    生成過(guò)程:
    打開(kāi)應(yīng)用程序中的“鑰匙串訪問(wèn)”軟件,從菜單中選擇 “鑰匙串訪問(wèn)”-》“證書(shū)助理”-》“從證書(shū)頒發(fā)機(jī)構(gòu)請(qǐng)求證書(shū)”滋戳,郵箱和名稱隨便填寫钻蔑,然后選擇保存到磁盤,就可以在本地生成一個(gè)CertificateSigningRequest.certSigningRequest文件胧瓜。

    (2)注冊(cè)一個(gè)支持push的app id矢棚,后面會(huì)用到。
    生成過(guò)程:
    進(jìn)入developer.apple.com府喳,選擇member center - Certificates, Identifiers & Profiles - Identifiers- App Ids蒲肋,然后選擇注冊(cè)app id,設(shè)置appid名稱钝满,同時(shí)兜粘,app id suffix一欄必須選擇explicit app id,然后設(shè)置bundle id弯蚜,最后勾選 App Services中的 Push Notifications孔轴,這樣就可以注冊(cè)一個(gè)支持push的aphid。

(3) 推送證書(shū)cer文件碎捺,該文件在developer.apple.com中生成路鹰,用于生成服務(wù)端需要的文件。
生成過(guò)程:
進(jìn)入developer.apple.com收厨,選擇member center - Certificates, Identifiers & Profiles - Certificates晋柱,然后選擇創(chuàng)建certificate,類型分為Development和Product诵叁。這里以Development為例雁竞,選擇Apple Push Notification service SSL (Sandbox) ,然后下一步拧额,選擇之前生成的支持push的AppId碑诉,然后下一步,提交之前創(chuàng)建的CSR文件侥锦,再下一步就可以生成cer文件进栽,然后保存到本地。

(4)生成服務(wù)端使用的證書(shū)文件恭垦。如果是使用網(wǎng)上的mac 版PushMeBaby工具泪幌,在mac機(jī)器上進(jìn)行推送消息的發(fā)送,那么有上面的cer文件就夠了署照。如果是使用PHP周蹭、java/c#開(kāi)發(fā)自己的服務(wù)端溉瓶,那么還需要將上面的cer文件做一個(gè)轉(zhuǎn)換,生成pem文件或者p12文件。

   生成php用的pem文件過(guò)程為:
    首先雙擊前面保存的cer文件编饺,此時(shí)會(huì)打開(kāi)“鑰匙串訪問(wèn)”軟件烁落,里面會(huì)出現(xiàn)一個(gè)Apple Development  IOS push services證書(shū),一個(gè)公用密鑰和一個(gè)專用秘鑰,秘鑰的名稱與證書(shū)助理中填寫的名稱一致阀湿。
  選中證書(shū),導(dǎo)出為 apns-dev-cert.p12 文件
  選中專有秘鑰瑰妄,導(dǎo)出為apns-dev-key.p12文件
  通過(guò)終端命令將這些文件轉(zhuǎn)換為PEM格式:
  openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
  openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
  最后陷嘴, 需要將兩個(gè)pem文件合并成一個(gè)apns-dev.pem文件,此文件在連接到APNS時(shí)需要使用:
  cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

  生成java/c#用的p12文件過(guò)程為:

  openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
  openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
  openssl pkcs12 -export -in apns-dev-cert.pem -inkey apns-dev-key.pem -certfile CertificateSigningRequest.certSigningRequest -name "push" -out push.p12

(5)生成XCODE使用的provisioning文件,該文件用于真機(jī)調(diào)試间坐。
生成過(guò)程:
進(jìn)入developer.apple.com灾挨,選擇member center - Certificates, Identifiers & Profiles - Provisioning Profiles,然后選擇創(chuàng)建Provisioning file竹宋,接著選擇iOS App Development 劳澄,下一步選擇AppId,選中之前建立的支持push的appid蜈七,接著下一步選擇支持push的certificate秒拔,下一步勾選需要支持的device id,最后一步設(shè)置provisioning文件的文件名飒硅,這樣provisioning文件就生成了砂缩。

3. 服務(wù)端的開(kāi)發(fā)
 (1)如果只是希望在mac電腦上測(cè)試一下消息的推送,可以使用PushMeBaby工具三娩,使用起來(lái)比較簡(jiǎn)單庵芭。該工具是開(kāi)源的,可以從https://github.com/stefanhafeneger/PushMeBaby 下載尽棕,代碼的執(zhí)行過(guò)程實(shí)際上就是設(shè)置一下SSL證書(shū),然后連接APNS彬伦,接著發(fā)送JSON數(shù)據(jù)滔悉。由于要處理SSL邏輯,因此代碼稍微多點(diǎn)单绑。在使用工具時(shí)回官,將工程資源中的cer文件替換成自己的cer文件,然后將代碼中的deviceToken替換成自己設(shè)備的deviceToken即可搂橙。


 (2)使用php開(kāi)發(fā)服務(wù)端
   由于php已經(jīng)內(nèi)置了ssl模塊歉提,因此使用php連接APNS服務(wù)器來(lái)發(fā)送json的過(guò)程實(shí)際上是很簡(jiǎn)單的,代碼如下:

該文件可以放到服務(wù)器中通過(guò)瀏覽器來(lái)訪問(wèn)区转,也可以通過(guò)命令行的方式來(lái)解釋執(zhí)行苔巨,代碼為:$ php -f Pusher.php

復(fù)制以下代碼
<?php
$deviceToken= ‘自己的deviceToken'; //沒(méi)有空格
$body = array("aps" => array("alert" => 'message',"badge" => 2,"sound"=>'default')); //推送方式,包含內(nèi)容和聲音$$ctx = stream_context_create();

//如果在Windows的服務(wù)器上废离,尋找pem路徑會(huì)有問(wèn)題侄泽,路徑修改成這樣的方法:
//$pem = dirname(FILE) . '/' . 'apns-dev.pem';
//linux 的服務(wù)器直接寫pem的路徑即可
stream_context_set_option($ctx,"ssl","local_cert","apns-dev.pem");
$pass = "xxxxxx";stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);//
//此處有兩個(gè)服務(wù)器需要選擇,如果是開(kāi)發(fā)測(cè)試用蜻韭,選擇第二名sandbox的服務(wù)器并使用Dev的pem證書(shū)悼尾,如果是正式發(fā)布柿扣,使用Product的pem并選用正式的服務(wù)器
$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);
?>

4. 客戶端的開(kāi)發(fā)
 (1)下載前面建立的cer文件和provisioning文件,雙擊闺魏,導(dǎo)入到xcode中未状,在build setting中code signing一欄里選擇這兩個(gè)文件的名稱,這樣就可以將支持push的app部署到真機(jī)中析桥。
 

 (2)處理推送消息
       客戶端對(duì)推送消息的處理分兩種情況:
      一. 在App沒(méi)有運(yùn)行的情況下司草,系統(tǒng)收到推送消息,用戶點(diǎn)擊推送消息烹骨,啟動(dòng)App翻伺。此時(shí),不會(huì)執(zhí)行前面提到的          didReceiveRemoteNotification函數(shù)沮焕,而是在App的applicationDidFinishLaunching函數(shù)中處理推送吨岭,通過(guò)以下代碼可以獲取推送消息中的數(shù)據(jù): NSDictionary *userInfo =[launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];


      二. 當(dāng)APP處于前臺(tái)時(shí),系統(tǒng)收到推送消息峦树,此時(shí)系統(tǒng)不會(huì)彈出消息提示辣辫,會(huì)直接觸發(fā)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo函數(shù),推送數(shù)據(jù)在userInfo字典中魁巩。

      三. 當(dāng)App處于后臺(tái)時(shí)急灭,如果系統(tǒng)收到推送消息,當(dāng)用戶點(diǎn)擊推送消息時(shí)谷遂,會(huì)執(zhí)行application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo函數(shù)葬馋,此時(shí)AppDelegate中函數(shù)執(zhí)行的順序?yàn)椋?          applicationWillEnterForeground
          application:didReceiveRemoteNotification
          applicationDidBecomeActive



 (3):將設(shè)備DeviceToken數(shù)據(jù)提供給服務(wù)商,以供推送到具體的手機(jī)上面. 如果遠(yuǎn)程推送消息來(lái)了,用戶點(diǎn)擊了推送消息,或者應(yīng)用已經(jīng)處于打開(kāi)狀態(tài),系統(tǒng)都會(huì)自動(dòng)調(diào)用以下委托:

  //點(diǎn)擊某條遠(yuǎn)程通知時(shí)調(diào)用的委托 如果界面處于打開(kāi)狀態(tài),那么此委托會(huì)直接響應(yīng)
    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    {
        NSLog(@"遠(yuǎn)程通知");
        [self PMD_uesPushMessage:userInfo];
    }

  //第三點(diǎn)里面的介紹的情況是應(yīng)用程序已經(jīng)處于運(yùn)行狀態(tài),上面的委托才會(huì)被執(zhí)行,如果應(yīng)用程序處于未啟用狀態(tài),此時(shí)又需要響應(yīng)消息,那么需要以下委托處理.
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        //這里處理應(yīng)用程序如果沒(méi)有啟動(dòng),但是是通過(guò)通知消息打開(kāi)的,此時(shí)可以獲取到消息.
        if (launchOptions != nil) {
            NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
            [self doSomeThingWith:userInfo];
        }
        return YES;
    }
5:清空通知中心已有的推送消息,只需要將指定App 的 Badge 設(shè)置為 0即可
    [[UIApplication sharedApplication ] setApplicationIconBadgeNumber:0];

6:主動(dòng)推送的字符串必須符合如下Json數(shù)組的格式,才能正確推送到手機(jī)當(dāng)中.
{
    
//自定義參數(shù)
\\"userinfo":
{
    \\"name":\\"remote notice"
},
//標(biāo)準(zhǔn)寫法
"aps":
{
    "alert":
    {
        "action-loc-key":"Open",//支持多語(yǔ)言
        "body":"messgae content"http://消息正文
    },
    "badge":1,//為App 的icon  標(biāo)記 具體數(shù)值
    "sound":"default" //播放的音頻文件,default 表示系統(tǒng)默認(rèn)的選擇列鈴聲
}
}


{"aps":{"alert":{"action-loc-key": "Open","body": "Hello, world!"},
        "badge":9,
        "sound":"default"
        }
}




deviceToken輸出不能用 [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  //傳遞直接傳遞 deviceToken 以下是輸出
  NSString *tokenString = [NSString stringWithFormat:@"%@",deviceToken];
  NSLog(@"tokenString - %@",tokenString);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肾扰,隨后出現(xiàn)的幾起案子畴嘶,更是在濱河造成了極大的恐慌,老刑警劉巖集晚,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窗悯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡偷拔,警方通過(guò)查閱死者的電腦和手機(jī)蒋院,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)莲绰,“玉大人欺旧,你說(shuō)我怎么就攤上這事「蚯” “怎么了切端?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)顷啼。 經(jīng)常有香客問(wèn)我踏枣,道長(zhǎng)昌屉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任茵瀑,我火速辦了婚禮间驮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘马昨。我一直安慰自己竞帽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布鸿捧。 她就那樣靜靜地躺著屹篓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匙奴。 梳的紋絲不亂的頭發(fā)上堆巧,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音泼菌,去河邊找鬼谍肤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哗伯,可吹牛的內(nèi)容都是我干的荒揣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼焊刹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼系任!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起虐块,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俩滥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后非凌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體举农,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荆针,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年敞嗡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片航背。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡喉悴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出玖媚,到底是詐尸還是另有隱情箕肃,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布今魔,位于F島的核電站勺像,受9級(jí)特大地震影響障贸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吟宦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一篮洁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧殃姓,春花似錦袁波、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至踏幻,卻和暖如春枷颊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叫倍。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工偷卧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吆倦。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓听诸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚕泽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晌梨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容