本文來自於騰訊bugly開發者社區,非經做者贊成,請勿轉載,原文地址:http://dev.qq.com/topic/58009392302e4725036142fchtml
Dev Club 是一個交流移動開發技術,結交朋友,擴展人脈的社羣,成員都是通過審覈的移動開發工程師。每週都會舉行嘉賓分享,話題討論等活動。ios
本期,咱們邀請了 騰訊 SNG iOS 開發工程師「段定龍」,爲你們分享《QQ電話適配iOS10 Callkit框架分享》。服務器
分享內容簡介:微信
蘋果在iOS 10開放了系統電話權限,全新的Callkit框架可以讓音視頻的第三方應用得到系統級的通話體驗,本次分享將主要介紹如何應用Callkit框架和一些適配經驗。網絡
下面是本期分享內容整理session
你們好,我是來自騰訊SNG的段定龍,目前負責QQ音視頻iOS客戶端的開發工做,很高興今天和你們分享一下QQ電話適配iOS10 Callkit的經驗。架構
今天將從4個方面進行分享:app
蘋果在2016年的WWDC大會上推出了iOS10,提供了一系列更加開放的新特性,其中最吸引咱們的就是Callkit,這個框架可以讓第三方應用得到系統電話的權限以及體驗。什麼概念呢?上圖吧。框架
這個框架解決了VoIP通話的三個痛點:ide
不得不給蘋果點個贊,需求已宣講,下面咱們來看看怎麼實現如此炫酷的體驗。
首先得介紹一下Callkit的框架。他分爲三大模塊:VoIP,CallCenter和來電屏蔽,要實現上述功能咱們只須要關注Voip模塊。Voip模塊裏主要有兩個類:CXProvider和CXCallController。
CXProvider能夠理解爲處理系統電話界面有關的邏輯,好比來電呼起系統電話界面或者將用戶在系統電話界面上的操做通知給App。 CXCallController則是將用戶在App界面上的操做通知給系統。
更具體地,網絡通話適配Callkit主要包含四個流程:收到來電主動通知Callkit、用戶在Callkit界面點擊接聽、用戶在手Q界面點擊掛斷、用戶在系統通信錄發起新的通話。下面將經過四個流程來介紹CXProvider、CXCallController、INIntent事件的使用,觸類旁通。
首先咱們看最簡單的收到來電主動通知Callkit:
收到服務器信令通知後只須要調用CXProvider的reportNewIncomingCall就能夠了。調用事後系統通信錄會自動沉澱,系統電話界面會展現。
圖中的setCategory是爲了不出現無聲問題,這個在後面會進行解釋。
而後是用戶在Callkit界面點擊接聽,這裏的流程通用於用戶對Callkit的操做回調:
用戶點擊接聽後,咱們會受到CXAnswerCallAction的回調,只須要在這裏面添加App原來的音視頻通話邏輯,再調用fulfill,整個流程就完成了。
再而後是用戶在App內點擊掛斷
這時候咱們須要添加一個CXEndCallAction到CXTransaction並調用requestTransaction請求執行,以後的流程與Callkit界面點擊接聽相似,收到CXEndCallAction回調,執行相應邏輯,調用fulfill完成流程。全部用戶在app內的操做都以這種方式通知Callkit。
最後咱們來看一下如何從App外部發起,以系統通信錄爲例子(Siri實際上是同樣樣的)
用戶在點擊系統通信錄的沉澱後,咱們會收到系統事件通知(INStartAudioCallIntent或者INStartVideoCallIntent),而後就相似於用戶在App內點擊掛斷的流程,只不過此次換成發起了,添加CXStartCallAction到CXTransaction並調用requestTransaction請求執行,收到CXStartCallAction的回調,執行相應邏輯後調用fulfill完成流程。
以上即是網絡通話中主要的4個場景流程,不知道你們對CXProvider和CXCallController的功能和使用場景是否已經有一個大體的瞭解。最後用一張圖來再解釋一下:
適配過總的結構如圖所示,系統界面由系統本身控制,咱們沒有辦法直接對其進行操做,這裏有點坑,有不少蘋果的BUG沒法避免,咱們須要CXCallController去通知系統更新,並經過CXProvider的回調處理在系統界面上的操做。
回顧了一下整個Callkit的架構後,下面將分享一些適配時候的經驗,包括ID的對應和無聲問題的處理
Callkit的架構裏有兩個ID標誌,UUID和CXHandle,前者是用於表示每一次通話,後者則是用於標識具體的用戶,好比reportNewIncomingCall的時候咱們須要新的UUID去標識此次通話,而在系統通信錄沉澱的時候,則使用CXHandle區分用戶。
QQ號碼是一套獨立的ID體系,區別於手機號,因此咱們須要定義特殊的CXHandle字符串,並將UUID,CXHandle和QQ本身的AVID聯繫起來,統一管理。
整個適配過程當中,咱們遇到最大的問題就是出現通話無聲問題,因爲沒有任何文檔,在無數次的嘗試後得出結論,蘋果對於Callkit和App的音頻接口調用順序有嚴格的要求,若是不按照一下順序來調用會出現無聲問題甚至Crash:
稍微給大夥兒一點時間,看看這個圖
圖中不一樣顏色表明不一樣的流程,系統音頻模塊(AVAudioSession)分爲六個操做:
重點其實就兩個:
最後提一下Pushkit通道的使用能夠保證用戶殺進程或者退後臺了,依然能夠後臺喚起進程,完成通話,不過這不是今天的重點,就帶過了。
因爲蘋果對整個架構真的沒有什麼文檔解釋,全部的工做都是在適配的過程當中進行摸索,每一個beta版本的接口都有所變更,太細節性的東西今天就不一一介紹了。
固然咱們能夠從一下途徑得到更多資料(聊勝於無)
官方文檔
WWDC2016視頻介紹
WWDC2016演示文檔
SpeakerBox: Using Callkit to create a VoIP app(9.13有更新的版本)
https://developer.apple.com/library/prerelease/content/samplecode/Speakerbox/Introduction/Intro.html
今天的分享講到這裏就結束拉,謝謝你們,若是有任何問題,歡迎你們提出來。
Q1:什麼是系統通信錄的沉澱是指在來電話後拒接,而後顯示在通話記錄裏嗎?
系統通信錄沉澱,就是好比打傳統電話的時候,咱們在電話app中最近通話裏會有此次通話的記錄,使用callkit後,全部未接,已接,呼出都會在最近通話中現實
Q2:uuid只是在通話中使用?若是發生變化有什麼影響?
uuid只是用於每次通話過程成表示本次通話,相同用戶的不一樣通話uuid是不一樣的,結束通話後這個uuid就沒有意義了。
Q3:系統通信錄打電話不是用的系統電話,能夠調起qq電話?
若是是由qq電話產生的通話記錄,那麼點擊發起的時候會調用qq電話。
Q4:pushkit來喚醒app,有失敗的可能嗎?可靠性如何?
有失敗的可能,好比咱們後臺向蘋果後臺發送,可是最終蘋果後臺沒有給客戶端下發,或者延時下發。目測仍是比較可靠的,具體數據我這沒有。成功率目測至少9成以上吧。
Q5:APP向下兼容到iOS7時,須要作些什麼處理呢?
這個特性只在iOS10上適用,注意作好版本保護就行。
Q6:在系統通話記錄中若是是 qq 電話,直接點擊會發起qq 電話,這就是你說的 pushkit 嘛,喚醒程序,剛試了下,中間有次次失敗了,還有就是對此次的通話 uuid,qq 的 id 這個是哪裏獲得的?
系統通話記錄點擊發起QQ電話並非Pushkit, 而是Callkit提供的新特性。uuid是APP內生成的,qq的AVID取決於不一樣業務,也能夠說是qq本身定義的。只是這是不一樣體系下的id須要作一些對應,通信錄發起時帶的是cxhandle。至於bug。麻煩提供一下號碼?後續跟進給你個答覆
Q7:除了在不按照順序來調用會出現無聲問題甚至Crash,還有其它什麼狀況會致使該問題的發生?
主要注意設置一下avaudiosession的類型爲playandrecord,否則也會致使無聲
更多精彩內容歡迎關注bugly的微信公衆帳號:
騰訊 Bugly是一款專爲移動開發者打造的質量監控工具,幫助開發者快速,便捷的定位線上應用崩潰的狀況以及解決方案。智能合併功能幫助開發同窗把天天上報的數千條 Crash 根據根因合併分類,每日日報會列出影響用戶數最多的崩潰,精準定位功能幫助開發同窗定位到出問題的代碼行,實時上報能夠在發佈後快速的瞭解應用的質量狀況,適配最新的 iOS, Android 官方操做系統,鵝廠的工程師都在使用,快來加入咱們吧!