【騰訊Bugly乾貨分享】QQ電話適配iOS10 Callkit框架

来源:http://www.cnblogs.com/bugly/archive/2016/10/24/5992895.html
-Advertisement-
Play Games

蘋果在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個方面進行分享:

  1. Callkit概述
  2. Callkit框架
  3. 適配經驗分享
  4. 更多資料

1. Callkit 概述

蘋果在2016年的WWDC大會上推出了iOS10,提供了一系列更加開放的新特性,其中最吸引我們的就是Callkit,這個框架能夠讓第三方應用獲得系統電話的許可權以及體驗。什麼概念呢?上圖吧。

這個框架解決了VoIP通話的三個痛點:

  1. 提高網路通話的音頻許可權:避免在通話過程中被傳統電話無腦打斷,更順暢!
  2. 可以使用系統電話的UI界面:QQ電話真正地變成了“電話”!
  3. 可以使用系統服務,豐富了入口:比如鎖屏的時候可以直接接聽,通過系統通話沉澱發起和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)

重點其實就兩個:

  1. 在流程開始前setCategory為PlayAndRecord
  2. 調用音頻模塊函數的時機:
    發起通話: Callkit回調 -> 初始化 -> fulfill -> 通知激活 -> 開啟音頻
    結束通話: Callkit回調 -> fulfill -> 通知結束 -> 關閉音頻 -> 去初始化

4. 結語

最後提一下Pushkit通道的使用可以保證用戶殺進程或者退後臺了,依然可以後臺喚起進程,完成通話,不過這不是今天的重點,就帶過了。

由於蘋果對整個架構真的沒有什麼文檔解釋,所有的工作都是在適配的過程中進行摸索,每個beta版本的介面都有所變動,太細節性的東西今天就不一一介紹了。

當然我們可以從一下途徑獲得更多資料(聊勝於無)

官方文檔

https://developer.apple.com/reference/callkit

WWDC2016視頻介紹

https://developer.apple.com/videos/play/wwdc2016/230/

WWDC2016演示文檔

http://devstreaming.apple.com/videos/wwdc/2016/230b83wfxc7m69dm90q/230/230_enhancing_voip_apps_with_callkit.pdf

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 官方操作系統,鵝廠的工程師都在使用,快來加入我們吧!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 裝飾者模式筆記 在不改變原對象的基礎上, 通過對其進行包裝拓展(添加屬性或方法)使原有對象可以滿足用戶的更複雜要求。 需求不是一成不變的,需求會不斷改進,以增強用戶體驗 demo實例:對輸入框添加focus與blur事件 這個實例中,輸入框只有一兩個時,新添需求不覺得麻煩,當有許多輸入框都要新添需求 ...
  • directive裡面的幾個配置,上代碼就清晰了 這段代碼在瀏覽器上打開是這樣的, 看到嗎,directive裡面的template在標簽的裡面,是標簽的子元素 然後再看,在配置一個replace replace為true的時候可以看到的是原來的自定義標簽被template替代了 要是restric ...
  • 這裡多謝某童鞋的提醒!說我的上篇隨筆jquery插件開發的方式一還還可用於合併參數和深clone,雖然方式二中用了方式一做參數合併,但並未詳細介紹,所以今天在此處做點補充! 一、合併參數 jquery的extend擴展原型: 返回值未arg1,arg2……合併到arg。這裡就有兩種用法。 省略arg ...
  • avalon.js是一款迷你的MVVM框架,設計者將其相容到了IE6。輕巧的體積和良好的相容使它非常適合國內的某些項目(學校、政府、銀行)。然而有時候居然出現了在ie上無法渲染的情況。 例如下列這段簡單的demo: 在chrome上的顯示是: 而在ie8上顯示卻是這樣: 大家不要慌張,可能是你加入了 ...
  • 一,JS模塊化演變過程 1.普通函數封裝 最初的這種普通函數封裝的缺點很明顯:污染了全局變數,無法避免的會與其他模塊發生變數名衝突,而且自身模塊成員之間沒有任何聯繫,,說白了就是沒有做到“高內聚,低耦合”原則 2.對象 技術一直在進步,這種做法的避免了變數污染,只要保證模塊名唯一即可,自身模塊內的成 ...
  • 所謂彈性滾動就是指在翻動長頁面手指離開時,有由慢到塊,由快到慢的過度。 安卓平臺上的大多數瀏覽器都預設了該行為 ios當前還只對<body>下的 overflow 預設產生彈性滾動效果 前一陣子做了一個手機官網,用到了 <div> 中的 overflow,再調試 ios 中遇到了彈性滾動的問題: i ...
  • javascript的一切實例都是對象,只是對象之間稍有不同,分為基本類型和引用類型。 基本類型對象指的是字元串(String)、數值(Number)、布爾值(Boolean),引用類型對象指的是數組(Array)、對象(Object)、函數(Function)。 這兩類數據的引用有差別。普通對象存 ...
  • /** * 獲取程式包名(本程式包名5.0版本上下都可獲取) * * @return */ public String getTaskPackname() { ActivityManager.RunningAppProcessInfo currentInfo = null; Field field  ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...