CallKit的功能介紹
CallKit可以幫我們的網(wǎng)絡(luò)電話提供怎樣更好的體驗(yàn)?
鎖屏?xí)r,有一個(gè)來(lái)電,現(xiàn)在是這樣的

就是一條普通的推送信息,看起來(lái)和iMessage的一條信息沒(méi)有什么區(qū)別。
沒(méi)有鎖屏?xí)r,如下,都是需要點(diǎn)擊后進(jìn)入應(yīng)用內(nèi)再進(jìn)行操作。

CallKit會(huì)帶來(lái)怎樣的改變呢,我們可以看下,
鎖屏?xí)r,有一個(gè)來(lái)電

非鎖屏?xí)r,有來(lái)電

接聽(tīng)后

讓你的網(wǎng)絡(luò)電話有類似iphone自帶電話的體驗(yàn),確實(shí)很cool
而且call kit還可以讓你的在線電話應(yīng)用和系統(tǒng)電話,F(xiàn)aceTime音頻通話,甚至是其他網(wǎng)絡(luò)電話相互作用

從系統(tǒng)通訊錄,通話記錄中打開(kāi)你的電話應(yīng)用

通過(guò)Siri,藍(lán)牙調(diào)起你的電話應(yīng)用撥打電話。系統(tǒng)的免打擾設(shè)置對(duì)你的應(yīng)用也是有效的。這就是CallKit。
CallKit的類和分工

CallKit有兩個(gè)主要的類CXProvider和CXCallController
CXProvider可以將一些外來(lái)事件通知給系統(tǒng)

CXCallController可以讓系統(tǒng)收到App的一些Request,用戶的action,內(nèi)部的事件。還可以完成上面說(shuō)的與其他的電話應(yīng)用進(jìn)行交互的操作。

Provider想要和系統(tǒng)交互,通過(guò)CXCallUpdate來(lái)傳遞信息

系統(tǒng)想要Provider知道用戶進(jìn)行那種操作,通過(guò)CXAction來(lái)傳遞信息

controller想要系統(tǒng)知道用戶進(jìn)行了什么操作,通過(guò)CXTransaction承載信息

Incoming Call的Demo
先看一下接電話的例子

Demo中有兩個(gè)比較關(guān)鍵的類SpeakerboxCallManager和SpeakerboxCall
SpeakerboxCallManager是通話的管理類,可以完成撥打電話,掛斷電話等功能。
SpeakerboxCall是通話的Model類,保存通話的一些信息。
我們新創(chuàng)建一個(gè)ProviderDelegate,它實(shí)現(xiàn)了CXProviderDelegate。

初始化方法中,創(chuàng)建了CXProvider對(duì)象,設(shè)置了Delegate,如果沒(méi)有用戶授權(quán)的話,請(qǐng)求用戶授權(quán)。

可以看到初始化CXProvider對(duì)象時(shí)還會(huì)進(jìn)行一些配置,包括通話中UI上顯示的應(yīng)用的名字,是否支持視頻,應(yīng)用的icon。代碼中配置每組中最多有一個(gè)通話,也就是不會(huì)出現(xiàn)同時(shí)接聽(tīng)兩個(gè)以上通話的情況。

下面看下當(dāng)一個(gè)電話打進(jìn)來(lái)的時(shí)候,我們應(yīng)該怎樣處理
首先,我們會(huì)接到推送通知

如果是voip類型的推送,我們可以解析到UUID(通話的唯一標(biāo)識(shí)),handle(誰(shuí)打的電話)
調(diào)用ProviderDelegate的方法,通知系統(tǒng)顯示Incoming Call的全屏UI,

注意CXProvider通知系統(tǒng)來(lái)電話了,是通過(guò)CXCallUpdate傳遞的信息。
實(shí)際代碼效果

當(dāng)用戶點(diǎn)擊接聽(tīng),我們還需要對(duì)CXProviderDelegate的代理方法進(jìn)行處理

可以看到系統(tǒng)反饋的用戶操作是CXAnswerCallAction,它是CXAction的一種。
CXAction有兩種狀態(tài),出錯(cuò)調(diào)用fail(),成功調(diào)用fulfill()。這個(gè)操作是必須的,系統(tǒng)才能正確處理UI的顯示和進(jìn)行通話狀態(tài)的控制。

當(dāng)接聽(tīng)用戶需要掛斷電話的時(shí)候,同樣是處理代理方法

這里還需要強(qiáng)調(diào)一點(diǎn),在call的處理過(guò)程中,開(kāi)發(fā)者還需要管理好AudioSession,具體可以參看Demo源碼。
Outgoing Call的Demo
撥打電話的處理起來(lái)會(huì)稍微復(fù)雜一點(diǎn),先看下生命周期示意圖

我們看下SpeakerboxCallManager中撥打電話的實(shí)現(xiàn)


撥打電話的時(shí)候我們會(huì)生成一個(gè)CXTransaction,它包含一組CXAction,Demo中是CXStartCallAction。
調(diào)用CXCallController對(duì)象的request方法,請(qǐng)求Start Call。
當(dāng)系統(tǒng)接受request,進(jìn)入start call狀態(tài)后,會(huì)通過(guò)CXProviderDelegate的代理方法通知App,也就是Demo中的ProviderDelegate。

代碼中會(huì)執(zhí)行App撥打電話的邏輯,并且設(shè)置connecting和connected的回調(diào)block,這樣才能保證call的生命周期處理,讓CXProvider正確的更新?tīng)顟B(tài)。
如果支持通過(guò)Siri或者電話通訊錄等喚醒你的應(yīng)用,進(jìn)行撥打電話的操作,實(shí)現(xiàn)AppDelegate的方法。

實(shí)際效果如下


連接成功后

我們回到桌面,應(yīng)用進(jìn)入后臺(tái)

可以看到系統(tǒng)上方會(huì)顯示通話中的提示。點(diǎn)擊后可以回到應(yīng)用。
總結(jié)
CallKit到目前為止只提供了講解視頻,沒(méi)提供編程指南,更多更復(fù)雜的功能可能需要等待具體的文檔來(lái)了解了,比如同時(shí)有多個(gè)通話處理等。