PushKit 的簡單實(shí)驗(yàn)

最近為了解決工作中的問題谣辞,看到了iOS 8開始迫摔,蘋果的PushKit。簡單實(shí)驗(yàn)了一番泥从,雖然最后也沒有用這個(gè)神器解決問題句占,總結(jié)一下。

1躯嫉,PushKit是不同于APNs的另外一種推送纱烘,用于VoiP的業(yè)務(wù)杨拐。據(jù)說是只提供給網(wǎng)絡(luò)電話APP使用,如果不提供此功能的APP使用了這個(gè)功能擂啥,會增加審核被拒的風(fēng)險(xiǎn)哄陶。

2,需要單獨(dú)申請證書哺壶,不能使用Wildcard證書屋吨,申請方法如下(不貼圖了,文字足夠了):
1)進(jìn)入開發(fā)者中心山宾,登錄至扰;
2)左側(cè)選"Certificates, IDs & Profiles", 進(jìn)入證書申請頁;
3)確認(rèn)要加入PushKit功能的APP ID存在资锰,左側(cè)"Identifiers"->"App IDs"敢课,右側(cè)列表查看希望使用PushKit的APP ID是否在列表里,如果不在绷杜,點(diǎn)右上角 + 手動(dòng)添加bundle Id(一般情況下Xcode會自動(dòng)創(chuàng)建)直秆;
4)左側(cè)"Certificates"->"All",右側(cè)選 + 接剩,增加一個(gè)證書切厘;
5)單選"VoIP Services Certificate" -> "Continue";
6)Select an App ID for your VoIP Service Certificate 列表懊缺,APP ID 列表里選擇要添加PushKit功能APP的bundle ID疫稿,然后"Continue";
7)一直"Continue"鹃两,中間需要選擇一次CertificateSigningRequest.certSigningRequest遗座,完成后,下載證書voip_services.cer進(jìn)行安裝(此證書需要在server端使用)
8)檢查證書在KeyChain中是否安裝成功
如果PushKit服務(wù)器需要使用pem文件俊扳,那么使用openssl生成文件途蒋,與APNs推送的類似。

3馋记,需要在Xcode中号坡,給相應(yīng)的APP(target)勾選 Capabilities。
1)注意梯醒,Push Notifications也要是ON宽堆,否則無法獲取注冊token;
2)Background Modes , 勾選 Voice over IP茸习,Background fetch 和 Remote notifications

配置結(jié)束畜隶,下面是代碼部分。
我實(shí)驗(yàn)的內(nèi)容是,收到PushKit推送后籽慢,發(fā)送本地推送浸遗。
APP端代碼:

AppDelegate.h
// 添加如下代碼
#import <PushKit/PushKit.h>
// 添加delegate
PKPushRegistryDelegate
AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       
// 注冊PushKit
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue: nil];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject: PKPushTypeVoIP];

// 注冊push權(quán)限,用于顯示本地推送
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
  return YES;
}

// PushKit delete
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
    
//去掉server發(fā)回來token中的<>箱亿,空格不去掉跛锌,具體情況視PushKit server決定
NSString * tokenString = [[[credentials.token description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""];
NSLog(@"PushKit toke: %@", tokenString);
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type {
    
// 從payload中獲取推送信息
NSDictionary *dic = payload.dictionaryPayload;
NSDictionary *apsDic = dic[@"aps"];
NSString *msgId = dic[@"mssage_id"];

// 此處也可以根據(jù)message_id獲取消息具體內(nèi)容,然后在block中發(fā)送本地推送
// ...

// 生成本地推送
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate date];
localNotification.alertBody = apsDic[@"alert"];  
localNotification.soundName = @"default";
localNotification.alertTitle = @"一條來自PushKit的推送";
localNotification.userInfo = [[NSDictionary alloc] initWithObjectsAndKeys: msgId, @"msgid", nil];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}

-(void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type {
NSLog(@"didInvalidatePushTokenForType");
}

APP端的處理很簡單届惋。

下面是PushKit server察净,我使用的是Mac上直接能使用的 PushMeBaby,github地址:https://github.com/stefanhafeneger/PushMeBaby

Payload格式盼樟,可以任意自定義:
{
"aps": {
"alert": "Hello"
},
"message_id": "xxxxxxxxxx"
}

遇到的坑:
1,github下載到的是debug版锈至;
2晨缴,PushMeBaby使用的token只需要去掉<和>,空格不能去掉峡捡,去掉后APP收不到推送击碗;(這是我最初一直發(fā)送推送APP收不到的原因)
3,ApplicationDelegate.m中self.certificate是證書的路徑们拙,需要把下載到的證書添加進(jìn)工程稍途,具體方法:
File->Add files to "PushMeBaby",直接把voip_services.cer文件添加進(jìn)工程砚婆,必要時(shí)進(jìn)行拷貝械拍;
確保cer文件的文件名與self.certificate設(shè)置的一致:

self.certificate = [[NSBundle mainBundle] pathForResource:@"voip_services" ofType:@"cer"];

4,release版本與debug中的差別:
debug:

// Establish connection to server.
PeerSpec peer;
result = MakeServerConnection("gateway.sandbox.push.apple.com", 2195, &socket, &peer); NSLog(@"MakeServerConnection(): %d", result);

// Set server domain name.
result = SSLSetPeerDomainName(context, "gateway.sandbox.push.apple.com", 30); NSLog(@"SSLSetPeerDomainName(): %d", result);
// 30是前面字符串的長度

release

// Establish connection to server.
PeerSpec peer;
result = MakeServerConnection("gateway.push.apple.com", 2195, &socket, &peer); NSLog(@"MakeServerConnection(): %d", result);

// Set server domain name.
result = SSLSetPeerDomainName(context, "gateway.push.apple.com", 22); NSLog(@"SSLSetPeerDomainName(): %d", result);
// 22是前面字符串的長度

實(shí)驗(yàn)結(jié)果:
1)APP在前臺装盯,收到PushKit推送后坷虑,發(fā)送本地推送,APP不提示埂奈;(與其他remote notification一致)迄损;
2)APP在后臺,或者被closed的狀態(tài)下账磺,都能收到PushKit推送芹敌,并發(fā)出本地推送。我在另外一個(gè)稍微復(fù)雜點(diǎn)的測試中垮抗,在收到PushKit推送和發(fā)送本地推送之間氏捞,加入了根據(jù)message id在服務(wù)器獲取消息具體內(nèi)容的操作,也是正常的借宵,可見在APP closed時(shí)幌衣,由PushKit推送調(diào)起的網(wǎng)絡(luò)訪問也是正常的。
3)APNs silent push優(yōu)先級最低,然后是APNs普通推送豁护,優(yōu)先級最高的是PushKit推送哼凯。
4)APNs silent push和PushKit推送都能在APP處于后臺的時(shí)候,喚醒APP楚里,運(yùn)行30s断部,不同的是silent push在APP closed(用戶手動(dòng)killed,手機(jī)重啟或者APP被系統(tǒng)回收)時(shí)不能喚醒APP班缎,現(xiàn)象就是APP沒有反應(yīng)蝴光,而PushKit在APP closed的時(shí)候,仍然能夠喚醒APP达址,執(zhí)行一段代碼蔑祟。

猜測,在APP closed狀態(tài)下沉唠,系統(tǒng)收到silent push后其實(shí)有能力執(zhí)行APP的一段代碼疆虚,只不過silent push優(yōu)先級低,所以被忽略了~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末满葛,一起剝皮案震驚了整個(gè)濱河市径簿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘀韧,老刑警劉巖篇亭,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锄贷,居然都是意外死亡译蒂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門肃叶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹂随,“玉大人,你說我怎么就攤上這事因惭≡浪” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵蹦魔,是天一觀的道長激率。 經(jīng)常有香客問我,道長勿决,這世上最難降的妖魔是什么乒躺? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮低缩,結(jié)果婚禮上嘉冒,老公的妹妹穿的比我還像新娘曹货。我一直安慰自己,他們只是感情好讳推,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布顶籽。 她就那樣靜靜地躺著,像睡著了一般银觅。 火紅的嫁衣襯著肌膚如雪礼饱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天究驴,我揣著相機(jī)與錄音镊绪,去河邊找鬼。 笑死洒忧,一個(gè)胖子當(dāng)著我的面吹牛蝴韭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熙侍,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼万皿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了核行?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹬耘,失蹤者是張志新(化名)和其女友劉穎芝雪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體综苔,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惩系,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了如筛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片堡牡。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杨刨,靈堂內(nèi)的尸體忽然破棺而出晤柄,到底是詐尸還是另有隱情,我是刑警寧澤妖胀,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布芥颈,位于F島的核電站,受9級特大地震影響赚抡,放射性物質(zhì)發(fā)生泄漏爬坑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一涂臣、第九天 我趴在偏房一處隱蔽的房頂上張望盾计。 院中可真熱鬧,春花似錦、人聲如沸署辉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涨薪。三九已至骑素,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刚夺,已是汗流浹背献丑。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侠姑,地道東北人创橄。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像莽红,于是被迫代替她去往敵國和親妥畏。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

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