Telnyx-webrtc-ios
Enable Telnyx real-time communication services on iOS.Project Structure
- SDK project: Enable Telnyx WebRTC communications.
- SDK Tests project.
- Demo app project.
Project Setup:
- Clone the repository
- Run the command
pod installto install the dependencies inside the project root folder. - Open the Workspace :
TelnyxRTC.xcworkspace - Configure the Demo App (Optional):
- The
Config.xcconfigfile is included in the repository with default values - To use the Pre-call Diagnosis feature, edit
Config.xcconfigand set a valid phone number: - If you don’t need Pre-call Diagnosis, you can leave
PHONE_NUMBERempty
- The
- You will find 3 targets to build:
- The SDK
- The SDK Tests
- The Demo App

- Select the target
TelnyxRTC (TelnyxRTC Project)to build the SDK

- Select the target
TelnyxRTCTeststo run the tests. You will need to long press over the Run button and selectBuild for testing

- Select target
TelnyxWebRTCDemoto run the demo app. The SDK should be manually built in order to get the app running (Step 5)
SIP Credentials
In order to start making and receiving calls using the TelnyxRTC SDK you will need to get SIP Credentials:- Access to https://portal.telnyx.com/
- Sign up for a Telnyx Account.
- Create a Credential Connection to configure how you connect your calls.
- Create an Outbound Voice Profile to configure your outbound call settings and assign it to your Credential Connection.
Region Selection
The TelnyxRTC SDK supports connecting to different geographic regions to optimize call quality and reduce latency. The demo app includes a region selection feature that allows users to choose their preferred region.Available Regions
- Auto (Default): Automatically selects the best region based on network conditions
- US East: East coast United States servers
- US Central: Central United States servers
- US West: West coast United States servers
- Canada Central: Central Canada servers
- Europe: European servers
- Asia Pacific: Asia Pacific servers
Using Region Selection
- In the Demo App: Use the overflow menu (⋯) to access region selection. The current region is displayed as “Region: [current-region]”.
-
In Your App: Configure the region when creating a
TxServerConfiguration:
Region Selection Behavior
- During Active Calls: Region selection is automatically disabled during active calls to prevent connection disruption
- When Connected: Region selection is disabled when the client is connected to prevent disrupting the established connection
- Fallback Logic: If a regional server is unavailable, the SDK automatically falls back to the auto region
- Persistence: The selected region persists across app sessions until manually changed
Best Practices
- Use Auto region for the best overall experience unless you have specific latency requirements
- Select a region geographically close to your users for optimal call quality
- Test different regions in your target deployment areas to determine the best performance
Adding Telnyx SDK to your iOS Client Application:
Currently the iOS SDK is supported using cocoapods.Cocoapods
If your xcode project is not using cocoapods yet, you will need to configure it.- Open your podfile and add the TelnyxRTC.
- Install your pods. You can add the flag —repo-update to ensure your cocoapods has the specs updated.
- Open your .xcworkspace
- Import TelnyxRTC at the top level of your class:
- Disable BITCODE (The GoogleWebRTC dependency has BITCODE disabled): Go to the Build Settings tab of your app target, search for “bitcode” and set it to “NO”

- Enable VoIP and Audio background modes: Go to Signing & Capabilities tab, press the +Capability button and add those background modes:

- Go to your Info.plist file and add the “Privacy - Microphone Usage Description” key with a description that your app requires microphone access in order to make VoIP calls.

- You are all set!
Swift Package Manager
Xcode has a built-in support for Swift package manager. To add a package :- Select Files > Add Packages
- On the Swift Package Manager Screen, Search for the https://github.com/team-telnyx/telnyx-webrtc-ios.git package.
- Select the main brach and click Add Package
rm -rf ~/Library/Caches/org.swift.swiftpm/ in terminal
Read more in Apple documentation
Hint: Use either Cocoapods or Swift Package Manager for Individual Packages to avoid Duplicate binaries
Usage
Telnyx client setup
Telnyx client delegate
You will need to instantiate the client and set the delegate.Calls
Outboud call
Audio Session Handling WebRTC + CallKit section.
Inbound call
How to answer an incoming call:Setting up VoIP push notifications section.
Call Termination Reasons
When a call ends, the SDK provides detailed information about why the call was terminated through theCallTerminationReason structure. This information is available in the DONE state of the call.
CallTerminationReason Structure
TheCallTerminationReason structure contains the following fields:
cause: A string describing the general cause of the call termination (e.g., “CALL_REJECTED”, “USER_BUSY”)causeCode: A numerical code corresponding to the causesipCode: The SIP response code (e.g., 403, 404)sipReason: The SIP reason phrase (e.g., “Dialed number is not included in whitelisted countries”)
Accessing Call Termination Reasons
You can access the termination reason in theonCallStateUpdated delegate method:
Common Termination Causes
The SDK provides various termination causes, including:NORMAL_CLEARING: Call ended normallyUSER_BUSY: The called party is busyCALL_REJECTED: The call was rejectedUNALLOCATED_NUMBER: The dialed number is invalidINCOMPATIBLE_DESTINATION: The destination cannot handle the call type
WebRTC Statistics
The SDK provides WebRTC statistics functionality to assist with troubleshooting and monitoring call quality. This feature is controlled through thedebug flag in the TxClient configuration.
Enabling WebRTC Statistics
To enable WebRTC statistics logging:Understanding WebRTC Statistics
Whendebug: true is configured:
- WebRTC statistics logs are automatically collected during calls
- Logs are sent to the Telnyx portal and are accessible in the Object Storage section
- Statistics are linked to the SIP credential used for testing
- The logs help the Telnyx support team diagnose issues and optimize call quality
Real-time Call Quality Monitoring
The SDK provides real-time call quality metrics through theonCallQualityChange callback on the Call object. This allows you to monitor call quality in real-time and provide feedback to users.
Using onCallQualityChanged
CallQualityMetrics Properties
TheCallQualityMetrics object provides the following properties:
| Property | Type | Description |
|---|---|---|
jitter | Double | Jitter in seconds (multiply by 1000 for milliseconds) |
rtt | Double | Round-trip time in seconds (multiply by 1000 for milliseconds) |
mos | Double | Mean Opinion Score (1.0-5.0) |
quality | CallQuality | Call quality rating based on MOS |
inboundAudio | [String: Any]? | Inbound audio statistics |
outboundAudio | [String: Any]? | Outbound audio statistics |
remoteInboundAudio | [String: Any]? | Remote inbound audio statistics |
remoteOutboundAudio | [String: Any]? | Remote outbound audio statistics |
CallQuality Enum
| Value | MOS Range | Description |
|---|---|---|
.excellent | MOS > 4.2 | Excellent call quality |
.good | 4.1 ≤ MOS ≤ 4.2 | Good call quality |
.fair | 3.7 ≤ MOS ≤ 4.0 | Fair call quality |
.poor | 3.1 ≤ MOS ≤ 3.6 | Poor call quality |
.bad | MOS ≤ 3.0 | Bad call quality |
.unknown | N/A | Unable to calculate quality |
Best Practices for Call Quality Monitoring
-
User Feedback:
- Consider showing a visual indicator of call quality to users
- For poor quality calls, provide suggestions (e.g., “Try moving to an area with better connectivity”)
-
Logging:
- Log quality metrics for later analysis
- Track quality trends over time to identify patterns
-
Adaptive Behavior:
- Implement adaptive behaviors based on call quality
- For example, suggest switching to audio-only if video quality is poor
-
Performance Considerations:
- The callback is triggered periodically (approximately every 2 seconds)
Important Notes
-
Log Access:
- If you run the app using SIP credential A with
debug: true, the WebRTC logs will be available in the Telnyx portal account associated with credential A - Logs are stored in the Object Storage section of your Telnyx portal
- If you run the app using SIP credential A with
-
Troubleshooting Support:
- WebRTC statistics are primarily intended to assist the Telnyx support team
- When requesting support, enable
debug: trueinTxClientfor all instances - Provide the
debug IDorcallIdwhen contacting support - Statistics logging is disabled by default to optimize performance
-
Best Practices:
- Enable
debug: trueonly when troubleshooting is needed - Remember to provide the
debug IDorcallIdin support requests - Consider disabling debug mode in production unless actively investigating issues
- Enable
Custom Logging
The SDK provides a flexible logging system that allows you to implement your own custom logger. This feature enables you to route SDK logs to your preferred logging framework or format.Implementing a Custom Logger
To create a custom logger, implement theTxLogger protocol:
Using a Custom Logger
To use your custom logger, pass it to theTxConfig when initializing the client:
Default Logger
If no custom logger is provided, the SDK usesTxDefaultLogger which prints logs to the console with appropriate formatting and emojis for different log levels.
Important Notes
-
Log Levels:
- The
logLevelparameter inTxConfigstill controls which logs are processed - Custom loggers only receive logs that match the configured verbosity level
- The
-
Thread Safety:
- Ensure your custom logger implementation is thread-safe
- Log callbacks may come from different threads
-
Performance:
- Keep logging operations lightweight to avoid impacting call quality
- Consider asynchronous logging for heavy operations
-
Best Practices:
- Handle all log levels appropriately
- Include timestamps for proper log sequencing
- Consider log persistence for debugging
- Handle errors gracefully within the logger
Push Notifications Setup
In order to receive incoming calls while the app is running in background or closed, you will need to perform a set of configurations over your Mission Control Portal Account and your application. For detailed documentation on setting up push notifications, see:- App Setup - Configure your iOS app to receive VoIP push notifications
- Portal Setup - Set up your Telnyx Portal account with VoIP push credentials
- Troubleshooting - Debug common push notification issues
Testing VoIP Push Notifications
The repository includes a dedicated testing tool to help validate your VoIP push notification setup. This tool allows you to send test push notifications directly to your device using your own certificates and configuration. Location:push-notification-tool/ in the repository root
Quick Setup
What the Tool Does
- Validates Configuration: Tests your certificate files, bundle ID, and device token
- Sends Test Pushes: Generates VoIP notifications with SDK-compatible payload structure
- Provides Detailed Errors: Clear error messages to help identify configuration issues
- Supports Continuous Testing: Send multiple pushes, switch configurations, test different scenarios
- Smart Configuration Management: Saves settings between sessions for faster iteration
Perfect for Testing
- Certificate and environment validation
- Device token verification
- Payload structure compatibility
- Multi-device testing
- Troubleshooting push delivery issues
VoIP Push - Portal setup
During this process you will learn how to create a VoIP push credential and assign the credential to a SIP Connection. This process requires:- A Mission Control Portal Account.
- A SIP Connection.
- Your Apple VoIP push certificate.
VoIP Push - App Setup
The following setup is required in your application to receive Telnyx VoIP push notifications:a. Add Push Notifications capability to your Xcode project
- Open the xcode workspace associated with your app.
- In the Project Navigator (the left-hand menu), select the project icon that represents your mobile app.
- In the top-left corner of the right-hand pane in Xcode, select your app’s target.
- Press the +Capabilities button.

- Enable Push Notifications

b. Configure PushKit into your app:
- Import pushkit
- Initialize PushKit:
- Implement PKPushRegistryDelegate
- If everything is correctly set-up when the app runs APNS should assign a Push Token.
- In order to receive VoIP push notifications. You will need to send your push token when connecting to the Telnyx Client.
- You will need to login at least once to send your device token to Telnyx before start getting Push notifications.
- You will need to provide
pushMetaDatatoprocessVoIPNotification()to get Push calls to work. - You will need to implement ‘CallKit’ to report an incoming call when there’s a VoIP push notification. On iOS 13.0 and later, if you fail to report a call to CallKit, the system will terminate your app. More information on Apple docs
c. Configure CallKit into your App:
PushKit requires you to use CallKit when handling VoIP calls. CallKit ensures that apps providing call-related services on a user’s device work seamlessly together on the user’s device, and respect features like Do Not Disturb. CallKit also operates the system’s call-related UIs, including the incoming or outgoing call screens. Use CallKit to present these interfaces and manage interactions with them.
For more information about CallKit you can check the official Apple docs.
General Setup:
- Import CallKit:
- Initialize CallKit
- Implement
CXProviderDelegatemethods.
CallKit properly working with the TelnyxRTC SDK you need to set the audio device state based on the CallKit AudioSession state like follows:
- Starting A New Call : When ever you start a call, report to callkit using the
provider.reportCall()method.
- When user receives a Call : Use
provider.reportNewIncomingCall(with: uuid, update: callUpdate)to report an incoming call. This sends a request to callKit the to provide the native call interface to the user.
- When callee answers an outgoing call : Use
provider.reportOutgoingCall(with: callKitUUID, connectedAt:nil)to report a connected outgoing call. This provides the time when the outgoing call goes to active to callKit.
Best Practices when Using PushNotifications with Callkit.
- When receiving calls from push notifications, it is always required to wait for the connection to the WebSocket before fulfilling the call answer action. This can be achieved by implementing the CXProviderDelegate in the following way (SDK version >=0.1.11):
answerFromPush(answerAction: action) is called, Callkit sets the call state to connecting to alert the user that the call is being connected.
Once the call is active, the timer starts.
| Connecting State | Active Call |
|---|---|
endCallFromCallkit(endAction:action) method should be called from :
- Logs on the receiver’s end are essential for thorough debugging of issues related to push notifications. However, the debugger is not attached when the app is completely killed. To address this, you can simply put the app in the background. VOIP push notifications should then come through, and the debugger should capture all logs.
CXProviderDelegate delegate which invokes functions corresponding to
what action was performed on the callkit user interface.
- End and Accept or Decline : The end and accept button on the callkit user interface accepts the new call and ends the previous call.
Callkit then invokes the
CXAnswerCallActionandCXEndCallActionwhen the end and accept button is pressed. You can handle this scenario by
- Hold and Accept or Decline: The hold and accept button on the callkit user interface accepts the new call and holds the previous call.
Callkit then invokes the
CXSetHeldCallActionwhen the hold and accept button is pressed.
CXEndCallAction.
Disable Push Notification
Push notifications can be disabled for the current user by calling :Privacy Manifest
Support for privacy manifest is added from version 0.1.26Documentation:
For more information you can:- Clone the repository
- And check the exported documentation in:
docs/index.html
Support
Find official documentation here Questions? Comments? Building something rad? Join our Slack channel and share.License
MIT Licence © Telnyx