Mastering iOS CallKit: How QQ Voice Calls Integrated with iOS 10
This article walks through the fundamentals of iOS 10 CallKit, explains its three‑module architecture, details the four main call‑handling flows, shares practical integration tips for QQ VoIP, and addresses common pitfalls like silent‑audio issues and version compatibility.
Dev Club is a community for mobile developers to share technology, make friends, and expand networks. Each week it hosts guest talks and discussions.
In this session, Tencent SNG iOS engineer Duan Dinglong presents "Adapting QQ Call to iOS 10 CallKit".
1. CallKit Overview
At WWDC 2016 Apple introduced iOS 10 with the CallKit framework, allowing third‑party apps to obtain system‑level call permissions and UI. CallKit solves three VoIP pain points: improved audio permissions, native call UI, and system‑level entry points such as lock‑screen answering and Siri integration.
2. CallKit Framework
2.1 Overall Structure
CallKit consists of three main modules: VoIP, CallCenter, and Call Blocking. The VoIP module is the focus, exposing two key classes: CXProvider (handles system UI and forwards user actions to the app) and CXCallController (sends app actions to the system).
2.2 Four Main Call Flows
The integration covers four scenarios: receiving an incoming call notification, answering from the CallKit UI, ending a call from the app, and initiating a call from the system contacts (or Siri).
Incoming call notification
After receiving a server signal, call CXProvider.reportNewIncomingCall to let the system UI appear.
The setCategory call prevents silent‑audio issues (explained later).
Answering from CallKit UI
The CXAnswerCallAction callback lets the app insert its own audio/video logic and then call fulfill.
Ending a call from the app
Add a CXEndCallAction to a CXTransaction and request it; the callback follows the same pattern as answering.
Initiating a call from system contacts (or Siri)
The system sends an INStartAudioCallIntent or INStartVideoCallIntent. The app creates a CXStartCallAction, adds it to a transaction, and fulfills the callback.
3. QQ Voice/Video Architecture & Experience
3.1 ID Mapping
CallKit uses two identifiers: UUID for each call instance and CXHandle for the remote user. QQ maps its own AVID to these IDs, creating a custom CXHandle string.
3.2 Silent‑Audio Pitfall
The biggest issue encountered was silent audio caused by incorrect ordering of AVAudioSession calls. Apple requires a strict sequence; deviating can lead to silence or crashes.
Key points:
Set the audio session category to PlayAndRecord before the flow starts.
Follow the exact timing:
4. Conclusion
PushKit can keep the app alive in the background for incoming calls, but the focus here was CallKit integration. Because Apple provides little documentation, most solutions were discovered through trial and error, and interfaces may change across beta releases.
For more details see the official Apple CallKit documentation, WWDC 2016 videos, and sample projects such as SpeakerBox.
Interactive Q&A
Q1: What does “system contacts sinking” mean?
It refers to the call appearing in the recent calls list after a call (incoming, outgoing, or missed) when using CallKit.
Q2: Is UUID only used during a call?
Yes, each call gets a unique UUID; it becomes irrelevant after the call ends.
Q3: Can a system‑contact call launch QQ Call?
If the call record originates from QQ, tapping it will launch QQ’s call UI.
Q4: How reliable is PushKit for waking the app?
Failures can occur if Apple’s servers don’t deliver the push or there’s latency, but success rates are typically above 90%.
Q5: What to consider for iOS 7 compatibility?
CallKit is only available on iOS 10+, so guard the code with version checks.
Q6: Is the “system‑contact click” feature PushKit?
No, it’s a CallKit feature. The UUID is generated by the app; QQ’s AVID is defined by its own business logic.
Q7: Besides call‑order, what else causes silent‑audio?
Setting the AVAudioSession category to something other than PlayAndRecord can also cause silence.
Tencent TDS Service
TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
