沒想到做 PHP 還會(huì)接觸這方面的東西,感覺風(fēng)馬牛不相及,在這里碰頭了。從 PHP api到 Cordova 搭建打包 App再到里面的極光推送和小紅點(diǎn)的數(shù)值,真是禿了半邊頂。(話說回來,我們 BOSS 和個(gè)推可是校友,我可是力排眾議,毅然決然選擇了極光推,滑稽.jpg)
--萌新寄語
本篇主要介紹 Cordova 和 PHP 配合,完成極光推送消息( iOS 集成推送的證書申請(qǐng), PHP 推送代碼實(shí)現(xiàn))及角標(biāo)數(shù)值(badgeNum)的自我實(shí)現(xiàn)。多以截圖為主,直擊老鐵痛點(diǎn)。
這邊主要介紹 jpush ios 推送證書的申請(qǐng),申請(qǐng)好了的,可以直接跳下面 PHP 部分
先介紹下我的環(huán)境,我只用到了 jpush。所以申請(qǐng)極光賬號(hào)還是很簡(jiǎn)單的,不需要什么身份認(rèn)證。
一. 創(chuàng)建應(yīng)用后的操作
創(chuàng)建成功后的信息
其中 AppKey 是 Cordova 安裝 jpush 插件的必須 也是后面推送的必須(還有隱藏的
Master Secret)
- 下面就可以設(shè)置推送的相關(guān)信息了

安卓的無腦操作這里就不介紹了
注意包名一定要統(tǒng)一 避免不必要的麻煩,這里詳細(xì)介紹下 iOS 的證書設(shè)置(鑒權(quán)方式為 證書)我這里用的是個(gè)人開發(fā)者賬號(hào) $99 沒有證書、Mac 的之類的兄弟姐妹就早點(diǎn)兒下班休息吧航
首先需要用你的開發(fā)者賬號(hào)登陸蘋果開發(fā)者中心
-
然后打開這個(gè)慘絕人寰的頁面
找到這個(gè)頁面詳見url -
Development 顧名思義即開發(fā)證書
image.png -
點(diǎn)擊加號(hào)后出現(xiàn)的頁面 選中開發(fā)的按鈕后就可以下一步 continue 了
上面的就是開發(fā) 下面的是生產(chǎn) 一個(gè)個(gè)來吧 -
選擇以后繼續(xù) continue
image.png -
一直 continue 到這個(gè)頁面 選擇簽名 這個(gè)時(shí)候就需要 Mac 的鑰匙串去請(qǐng)求簽名證書了 這一步先放在這里
image.png -
Mac 請(qǐng)求證書
image.png -
請(qǐng)求成功之后,保存在本地,創(chuàng)建一個(gè)這個(gè)包名的文件夾 方便區(qū)分
image.png - 回到已經(jīng)打開的 蘋果開發(fā)者中心 選擇剛才存到本地的證書 down 下來
image.png
下載下來的 .cer 后綴的文件就是我們要的了。拖到鑰匙串中打開
按流程走就行了
下面就是導(dǎo)出 .p12 的文件了!?。?! 盼星星盼月亮 終于盼到這一步了
部分情況會(huì)出現(xiàn)不能導(dǎo)出 .p12 沒有這個(gè)選項(xiàng),請(qǐng)把證書拖到登陸里面,再次嘗試 -
走完下面這一步就大功告成了
注意事項(xiàng) 見圖 -
都是明白人兒 放進(jìn)去就行了。雖然下面有提示 是否將生產(chǎn)證書用于開發(fā)環(huán)境,想都別想,趁熱把另一個(gè)證書申請(qǐng)了吧
image.png - 開發(fā)證書和生產(chǎn)證書操作是一毛一樣的 兩個(gè)同時(shí)操作也行 也沒意見
噥 就上面的區(qū)別 -
最終結(jié)果
還不是美滋滋
PHP 端處理 badge 的思路的自我實(shí)現(xiàn)
關(guān)于推送的信息,一定要多看極光的控制臺(tái)。reg_id和msg_id 平臺(tái)信息等都在上面。方便你去查找錯(cuò)誤信息
1. 是要區(qū)分你是什么推送方式 PHP接口處理推送當(dāng)然是API嘍,還用想
幾個(gè)常用的信息,給大家劃了出來
之前一直不懂 Jpush 服務(wù)器的角標(biāo)值是怎么玩的,現(xiàn)在大概明白了。關(guān)于推送的 badge數(shù)量在我上面截圖紅圈的 badge 參數(shù)。這樣我們不要自己去計(jì)算角標(biāo)值,根據(jù)下面的兩個(gè)接口定義 就可以根據(jù)用戶是否點(diǎn)擊,在原有的基數(shù)上去對(duì)應(yīng)的增加減少即可 但是如果我們想要看到消息日志的話和推送日志方便自己管理的話 就要自己去建表存儲(chǔ)狀態(tài)了

大概思路是 這里我用了三張表去控制 大概實(shí)現(xiàn)了角標(biāo)的核銷。
數(shù)據(jù)表的設(shè)計(jì)
- 用戶每一次登陸都會(huì)去獲取一下設(shè)備的 id,也就是極光的 registration_id 。(防止設(shè)備 ID 改變,極光介紹,或者用戶更換手機(jī),能準(zhǔn)確的推送到該設(shè)備)
- message 表主要做存儲(chǔ)發(fā)送消息的記錄。方便后臺(tái)管理員了解曾經(jīng)推送過得信息。
-
message_log 表主要就是存儲(chǔ)推送的消息日志(用戶太多的話肯定要優(yōu)化數(shù)據(jù)表的,暫時(shí)不做考慮),根據(jù)表里的
status就可以判斷是否已讀,用戶每次點(diǎn)擊消息詳情頁都要去訪問下接口去修改status的狀態(tài),從而完成核銷。核銷的基礎(chǔ)是該用戶的 id 和消息 id,因?yàn)檫@兩個(gè)都是唯一的。
PHP 邏輯代碼簡(jiǎn)單的封裝了一下詳見 jpushPHPdemo
protected function pi_push($member_id,$content,$badgeNum,$array){
try {
// 配置引入
$app_key = PI_Config::APP_KEY;
$master_secret = PI_Config::MASTER_SECRET;
// use jpush
$client = new JPush($app_key, $master_secret);
$response = $client->push()
->setPlatform("all")
->addRegistrationId( $member_id )
->iosNotification( $content, array(
'sound' => 'sound.caf',
'badge' => "$badgeNum" + 1,
'content-available' => true,
'mutable-content' => true,
'extras' => $array
))
->androidNotification( $content, array(
// 'title' => ,
'extras' => $array
))
->options(array(
// !!!! apns_production:這里我試過去掉 option參數(shù) 以為默認(rèn)推送生產(chǎn)環(huán)境,其實(shí)不然。需要生產(chǎn)環(huán)境的推送的時(shí)候,最好指定?。。?
// True 表示推送生產(chǎn)環(huán)境,F(xiàn)alse 表示要推送開發(fā)環(huán)境;如果不指定則默認(rèn)為推送生產(chǎn)環(huán)境
'apns_production' => true,
))
->send();
if ( $response['http_code'] == 200) {
return $response['body']['msg_id'];
}else{
return false;
}
} catch (\JPush\Exceptions\APIConnectionException $e) {
return false;
} catch (\JPush\Exceptions\APIRequestException $e) {
return false;
}
}
下面執(zhí)行推送的代碼
// 手動(dòng)推送的設(shè)置
public function post_push( $request ){
$res['title'] = $request['title']; // 推送的標(biāo)題
$res['content'] = $request['content']; // 推送的內(nèi)容
$res['remark'] = $request['remark']; // 推送的備注
$res['create_date'] = date( "Y-m-d H:i:s" );
// 推送類型
$push_type = $request['push_type'];
// 推送前插入 推送記錄表 (WordPress的mysql insert方法)
if ( $push_type === '0' ) {
$info = $this->wpdb->insert(
$this->pi_message,
$res,
array( '%s', '%s', '%s' )
);
}
// 插入成功 推送并插日志表
if( $info ){
// 查找所有設(shè)備ID 上面接受過 每次登陸或者注冊(cè) 都要重新獲取一下reg_id
$find_sql = "SELECT device_id FROM $this->pi_bindinguser";
//設(shè)備ID的數(shù)組集合
$total_user = $this->wpdb->get_results( $find_sql, ARRAY_A );
// 找到所有的設(shè)備id 發(fā)送數(shù)據(jù)
foreach ($total_user as $key => $value) {
// 每個(gè)設(shè)備id
$device_id = $value['device_id'];
// 通過設(shè)備id 去查找 member_id 從而計(jì)算該用戶的未讀和已讀
$sql = "SELECT member_id FROM $this->pi_bindinguser WHERE device_id = ". " '$device_id' ";
// 計(jì)算badge_num的數(shù)值
$member_id = $this->wpdb->get_var( $sql );
// 獲取當(dāng)前的狀態(tài)為零 未讀取的小紅點(diǎn)
$total_sql = "SELECT count(id) FROM $this->pi_message_log WHERE member_id = $member_id AND status = 0" ;
//如果該用戶消息為空的話 即默認(rèn)為0開始
$badge_num = empty( $this->wpdb->get_var( $total_sql ) ) ? '0' : $this->wpdb->get_var( $total_sql );
$msg_id = $this->pi_push($device_id,$res['content'],$badge_num,$array);
// var_dump( $msg_id );
//推送成功之后 拿到msg_id 和 member_id 也就是消息id和用戶id 兩個(gè)對(duì)應(yīng)的數(shù)據(jù)唯一 去存入消息列表 做核銷使用
if( $msg_id ){
$time = date( "Y-m-d H:i:s" );
$info = $this->wpdb->insert(
$this->pi_message_log,
array('member_id'=>$member_id,'msg_id'=>$msg_id,'content'=>$res['content'],'create_date'=>$time,'push_type'=>$push_type),
array( '%s', '%s', '%s', '%s', '%s' )
);
}
}
return PI_Response::init( 0 );
}else{
return PI_Response::init( 1003 );
}
}
到此 推送和本地計(jì)算角標(biāo)值也就差不多了??蛻舳说?badge 改動(dòng)就要他們自己去掉 jpush 的接口了。因?yàn)槊坎榭匆淮蜗⒕腿ピL問接口的,這樣的話客戶端和服務(wù)端的角標(biāo)值的數(shù)值就對(duì)應(yīng)上了,有點(diǎn)像 ajax 的無刷新刪除
我是用蒲公英做的內(nèi)測(cè)版 App 發(fā)布的。事先打包了 ipa 。這種情況的推送,必須要生產(chǎn)證書,也就是上面說的
'apns_production' => true,
多看文檔
推送成功的條件:設(shè)備id、正確的 AppKey master secret 、環(huán)境和對(duì)應(yīng)的證書是否一致等。重要的事情說三遍 多看推送歷史詳情和社區(qū)
推送成功的前提

做完一套流程到后面才發(fā)現(xiàn)不需要自己控制消息日志,調(diào)用 jpush 的接口就可以去完成角標(biāo)數(shù)值的增刪設(shè)置、顯示對(duì)應(yīng)的小紅點(diǎn)。我問老大,我們這樣做是不是多余的。老大:相信極光,也相信我們自己。
「本文系極光征文 | 寫寫文章就能贏 Filco,豈不美滋滋的參賽文章」


















