前言
面對通話的通知需求,對方呼入,響起鈴聲和震動,提醒用戶,對方掛斷之后,鈴聲震動停止,普通的APNS通知,已經(jīng)不能達(dá)到我們想要的效果,所以需要一種可以用通知就喚醒我們APP的技術(shù),然后使用我們自己的代碼進行本地通知,控制通知的出現(xiàn)和消失,蘋果的解決方案就是VOIP,PushKit推送。
VOIP使用PushKit
PushKit是蘋果在iOS8之后推出的新框架,iOS10之后,蘋果更是禁止VOIP應(yīng)用在后臺使用socket長鏈接,PushKit可以說是為了VOIP而生,滿足實時性的同時,還能達(dá)到省電的效果,搭配蘋果自己的CallKit,可以呈現(xiàn)出類似原生電話通話的效果。
PushKit區(qū)別與普通APNs的地方是,它不會彈出通知,而是直接喚醒你的APP,進入回調(diào),也就是說,可以在沒點擊APP啟動的情況下,就運行我們自己寫的代碼,當(dāng)然,推送證書和注冊、回調(diào)的方法也和APNs不同,具體操作如下
1.注冊推送證書

和注冊普通的證書方法相同,我們只要類型選擇VoIP Services Certificate注冊就好,VoIP的證書只用一個生產(chǎn)環(huán)境(Production)的,開發(fā)環(huán)境(Development)也可以使用,不必糾結(jié)。
2.項目配置

和APNs一樣,需要在Project-> Capabilities里打開推送開關(guān)和設(shè)置后臺,需要注意的是,我這里使用的是XCode9,Background Modes的設(shè)置里沒有VoIP的選項,XCode8會有專門的VoIP選項也需要打開

3.代碼配置
工程和證書得設(shè)置好之后,就是我們代碼的編寫了:
import PushKit
在AppDelege里倒入PushKit框架
let pushRegistry = PKPushRegistry.init(queue: DispatchQueue.main)
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [PKPushType.voIP]
在didFinishLaunchingWithOptions使用代碼注冊,然后我們就要實現(xiàn)這個PKPushRegistryDelegate的回調(diào)方法
extension AppDelegate: PKPushRegistryDelegate {
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
let device = NSData(data: credentials.token)
let deviceId = device.description.replacingOccurrences(of:"<", with:"").replacingOccurrences(of:">", with:"").replacingOccurrences(of:" ", with:"")
print_debug("pushkit設(shè)備token:" + deviceId)
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
print_debug("收到pushkit推送!")
print_debug(payload.dictionaryPayload)
}
}
(PS:print_debug是我寫的一個只在開發(fā)環(huán)境打印的函數(shù))
在func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType)方法里,我們可以拿到PushKit的推送token,然后上傳給我們自己的服務(wù)器使用;
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType)方法是收到推送的回調(diào),我們可以在這里做一個本地通知來通知用戶來電,也可以通過PushKit推送掛斷信息來消除通知。
當(dāng)然,我們的代碼完全可以不放在回調(diào)里做,因為有PushKit推送消息進來的時候,APP已經(jīng)在后臺啟動了,就是說我們寫在didFinishLaunchingWithOptions里面的代碼已經(jīng)全部執(zhí)行了,所以我們的APP的正常生命周期已經(jīng)開始了,這樣我們的可操作性就大了很多,(某種意義上,我們可以使用PushKit在用戶不知道的情況下喚醒APP,有點作弊的感覺),就寫到這里,PushKit的使用就是這么簡單。
更新?。。?/h2>
最近用Xcode9開啟新的工程,繼續(xù)使用PushKit,遇到極其坑爹的問題,因為Xcode9的Background Modes里面取消了勾選voip的選項,結(jié)果導(dǎo)致pushkit注冊不成功,無法獲取到pushkit的token,爬了坑之后才發(fā)現(xiàn)這個問題,解決方法是在info.plist文件里手動添加App provides Voice over IP services

歡迎更正錯誤和交流,回復(fù)評論和私信皆可 ??