蘋果在iOS 10開放了系統電話許可權,全新的Callkit框架能夠讓音視頻的第三方應用獲得系統級的通話體驗,本次分享將主要介紹如何應用Callkit框架和一些適配經驗。 ...
本文來自於騰訊bugly開發者社區,非經作者同意,請勿轉載,原文地址:http://dev.qq.com/topic/58009392302e4725036142fc
Dev Club 是一個交流移動開發技術,結交朋友,擴展人脈的社群,成員都是經過審核的移動開發工程師。每周都會舉行嘉賓分享,話題討論等活動。
本期,我們邀請了 騰訊 SNG iOS 開發工程師“段定龍”,為大家分享《QQ電話適配iOS10 Callkit框架分享》。
分享內容簡介:
蘋果在iOS 10開放了系統電話許可權,全新的Callkit框架能夠讓音視頻的第三方應用獲得系統級的通話體驗,本次分享將主要介紹如何應用Callkit框架和一些適配經驗。
下麵是本期分享內容整理
大家好,我是來自騰訊SNG的段定龍,目前負責QQ音視頻iOS客戶端的開發工作,很高興今天和大家分享一下QQ電話適配iOS10 Callkit的經驗。
今天將從4個方面進行分享:
- Callkit概述
- Callkit框架
- 適配經驗分享
- 更多資料
1. Callkit 概述
蘋果在2016年的WWDC大會上推出了iOS10,提供了一系列更加開放的新特性,其中最吸引我們的就是Callkit,這個框架能夠讓第三方應用獲得系統電話的許可權以及體驗。什麼概念呢?上圖吧。
這個框架解決了VoIP通話的三個痛點:
- 提高網路通話的音頻許可權:避免在通話過程中被傳統電話無腦打斷,更順暢!
- 可以使用系統電話的UI界面:QQ電話真正地變成了“電話”!
- 可以使用系統服務,豐富了入口:比如鎖屏的時候可以直接接聽,通過系統通話沉澱發起和Siri喚起通話等
不得不給蘋果點個贊,需求已宣講,下麵我們來看看怎麼實現如此炫酷的體驗。
2. Callkit 框架
2.1 整體結構
首先得介紹一下Callkit的框架。他分為三大模塊:VoIP,CallCenter和來電屏蔽,要實現上述功能我們只需要關註Voip模塊。Voip模塊里主要有兩個類:CXProvider和CXCallController。
CXProvider可以理解為處理系統電話界面有關的邏輯,比如來電呼起系統電話界面或者將用戶在系統電話界面上的操作通知給App。 CXCallController則是將用戶在App界面上的操作通知給系統。
2.2 四個主要流程的介面模塊使用
更具體地,網路通話適配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的對應和無聲問題的處理
3. 手Q適配框架及經驗
3.1 適配手Q音視頻架構
Callkit的架構里有兩個ID標誌,UUID和CXHandle,前者是用於表示每一次通話,後者則是用於標識具體的用戶,比如reportNewIncomingCall的時候我們需要新的UUID去標識這次通話,而在系統通訊錄沉澱的時候,則使用CXHandle區分用戶。
QQ號碼是一套獨立的ID體系,區別於手機號,所以我們需要定義特殊的CXHandle字元串,並將UUID,CXHandle和QQ自己的AVID聯繫起來,統一管理。
3.2 無聲問題的坑
整個適配過程中,我們遇到最大的問題就是出現通話無聲問題,由於沒有任何文檔,在無數次的嘗試後得出結論,蘋果對於Callkit和App的音頻介面調用順序有嚴格的要求,如果不按照一下順序來調用會出現無聲問題甚至Crash:
稍微給大伙兒一點時間,看看這個圖
圖中不同顏色代表不同的流程,系統音頻模塊(AVAudioSession)分為六個操作:
- 初始化(AudioUnitInit)
- 去初始化(AudioUnitUninit)
- 通知激活(didActivateSession)
- 開啟音頻(AudioUnitStart)
- 通知結束(didDeativateSession)
- 關閉音頻(AudioUnitStop)
重點其實就兩個:
- 在流程開始前setCategory為PlayAndRecord
- 調用音頻模塊函數的時機:
發起通話: Callkit回調 -> 初始化 -> fulfill -> 通知激活 -> 開啟音頻
結束通話: Callkit回調 -> fulfill -> 通知結束 -> 關閉音頻 -> 去初始化
4. 結語
最後提一下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 官方操作系統,鵝廠的工程師都在使用,快來加入我們吧!