Skip to contentSkip to navigationSkip to topbar
On this page

Voice Mobile SDKs: Best Practices


Twilio Programmable Voice SDKs allow you to add voice-over-IP (VoIP) calling directly into your web and native mobile applications. This page provides some known best practices to make implementation easier and reliable.

You connect to Twilio from your mobile app with the Voice Mobile SDKs (Android or iOS). To learn more about how Twilio communicates with your mobile app, read over the Voice SDK Overview page.


On this Page

on-this-page page anchor

Click on a link below to jump to a specific section.

To get the most out of this guide, use it in conjunction with the Voice iOS or Android SDK Quickstarts and documentation.


SDK logs will help your team or Twilio Support to identify issues. Be sure to set the log level to debug or verbose (see examples below) as a first step.

These detailed logs can be shared when you open a GitHub issue or Twilio Support ticket (just remember to redact any sensitive information first).

Android: Set the log level to DEBUG.

Voice.setLogLevel(LogLevel.DEBUG)
voice_android_sdk_debug1.
voice_android_sdk_debug2.

iOS: Set the log level to TVOLogLevelVerbose or .verbose

1
/* Obj-C */
2
[VoiceClient setLogLevel:TVOLogLevelVerbose];
3
1
/* Swift */
2
VoiceClient.logLevel = .verbose
voice_ios_sdk_debug1.
voice_ios_sdk_debug2.

Push registration and lifecycle

push-registration-and-lifecycle page anchor

Register for push notifications on every application

register-for-push-notifications-on-every-application page anchor

iOS: To ensure Apple VoIP push notification delivery, initialize the PushKit PKPushRegistry instance at app launch (e.g. in AppDelegate). This allows your app to receive notification in different states, especially when the app is relaunched from the terminated state. This also eliminates the need to check if registration exists or not.
Note: This functionality is already included in the Voice iOS SDK Quickstart(link takes you to an external page).

Push registration Time-To-Live (TTL) is one year of idle time

push-registration-time-to-live-ttl-is-one-year-of-idle-time page anchor

It's important to unregister from push notifications using the SDK's unregister methods (iOS SDK method(link takes you to an external page), Android SDK method(link takes you to an external page) when re-launching applications with different Voice SDK identity. Otherwise your app might receive pushes for the previously logged in user.
Note: This functionality is NOT included in the Android or iOS Quickstarts.

Push deregistration when uninstalling the application is still not fully solved due to operating system limitations

push-deregistration-when-uninstalling-the-application-is-still-not-fully-solved-due-to-operating-system-limitations page anchor

We rely on the operating system (OS) to stop providing push notifications for apps that are no longer installed. Therefore, if the app is uninstalled before deregistration, bindings can become stale and cause issues. If the app is reinstalled and identity reregistered, things will start to work again.
iOS: APNS & iOS do not detect if the app has been uninstalled and will still try to deliver push notifications to the binding upon being requested by Twilio Notify, i.e. Notify has no way of knowing the app is uninstalled since there is no error.
Since the PushKit device token will be the same on the same device and the same app (unless iOS is reinstalled or reset/restored), registering with a new identity when reinstalling the app will deactivate the old binding and activate the binding for the new identity.

Store the device token provided by the OS in persistent memory

store-the-device-token-provided-by-the-os-in-persistent-memory page anchor

To avoid excessive registrations, you should save the device provided by the OS in the persistent memory. Compare the values on startup and re-register only if the tokens differ.

See an example of this in the iOS Quickstart(link takes you to an external page).

React to device token changes provided by the OS events and re-register with new token

react-to-device-token-changes-provided-by-the-os-events-and-re-register-with-new-token page anchor

Android

android page anchor
  1. React to the new device token (See See Android SDK Quickstart example(link takes you to an external page))

    1
    public void onNewToken(String token) {
    2
    super.onNewToken(token);
    3
    Intent intent = new Intent(Constants.ACTION_FCM_TOKEN);
    4
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    5
    }
  2. Re-register for call invites with new token (See Android SDK Quickstart example(link takes you to an external page))

    1
    case Constants.ACTION_FCM_TOKEN:
    2
    registerForCallInvites();
    3
    break;

iOS: Use different Twilio accounts for development and production apps to avoid getting invalid APNS token error

ios-use-different-twilio-accounts-for-development-and-production-apps-to-avoid-getting-invalid-apns-token-error page anchor

Developers often use the same device while testing the development and production versions of their apps. Errors can occur if the developer uses the same client identity for each of the versions of the app on the same device.
Assuming the developer configures the Push Credential sandbox option correctly and has registered the identity in both development and production apps, there will be two active bindings existing in the Twilio Notify database. These two bindings each have an associated device token, which is development- or production-specific. Over time, the certificate and Push Credential associated with each binding may expire or become invalid and will result in errors when calling the client.
You should use a Twilio subaccount for creating AccessTokens for development and a different Twilio subaccount (or the primary Twilio account) for creating AccessTokens for the app version you will submit to the App Store.

iOS: Avoid using the same device during development for production app installation

ios-avoid-using-the-same-device-during-development-for-production-app-installation page anchor

When you run a different environment (development then production, or vice versa) for the first time, PushKit will return the device token from the previous environment, which may not match the sandbox configuration of the Push Credential in the AccessToken. This won't result in a registration failure, but "Invalid device token" errors will occur when Twilio sends the Push Notification delivery request to APNS.


Network considerations for the Voice Mobile SDKs

network-considerations-for-the-voice-mobile-sdks page anchor

Restrictive networks may fail unless ICE servers are provided via Connect Options or Accept Options. ICE servers can be obtained fromTwilio Network Traversal Service.

By default, ICE gathering is done on all interfaces except some VPN type interfaces. This makes it impossible to connect to Twilio in networks that require the use of VPN. The Boolean property to enable ICE gathering on any address ports in Connect Options should be enabled to allow the gathering of ICE candidates from all available interfaces.

1
// Android
2
ConnectOptions.Builder builder = new
3
ConnectOptions.Builder(accessToken);
4
5
builder.enableIceGatheringOnAnyAddressPorts(true);
1
// iOS
2
let connectOptions = ConnectOptions(accessToken: accessToken) { builder in
3
builder.params = [“foo”: “bar”]
4
builder.uuid = uuid
5
builder.enableIceGatheringOnAnyAddressPorts = true
6
}
7
8
let call = TwilioVoiceSDK.connect(options: connectOptions, delegate: self)

You may want to set your AccessTokens' time to live (TTL) to be several hours, with 24 hours as the maximum TTL.

AccessTokens are how Twilio tracks your Voice SDK usage (and how much your account should be billed). Keep AccessTokens secure.

Keep AccessTokens up to date. You should add logic to your application that automatically keeps AccessTokens up to date that follows the steps below:

  1. Confirm the TTL that is set in the AccessToken.
  2. Create a timer that will track the TTL, starting at the time your mobile app receives the AccessToken and ending about 30 seconds before the AccessToken's expiration. (e.g. timer length = TTL - 30 seconds)
  3. Re-register the device with the new AccessToken using the same register method used at startup.

Threading Considerations

threading-considerations page anchor

Android: All API calls must originate from the same thread & that thread must have a looper

android-all-api-calls-must-originate-from-the-same-thread--that-thread-must-have-a-looper page anchor

On Android, all Twilio Voice API calls must originate from the same thread and that thread must contain a Looper(link takes you to an external page). Many API calls invoke callbacks to notify the API user of state changes. In order for these messages to be invoked on the same thread as the thread that the API call originated from, a Looper(link takes you to an external page) is necessary. For an example of how to make all the API calls from the same thread, please look at the Android Voice Quickstart.


Mobile Push Credential Management

mobile-push-credential-management page anchor

If you need to change or update your push credentials you can do so by selecting the Push Credential in the console(link takes you to an external page) and adding your new certificate and private key in the text box provided on the Push Credential page. If your APNS VoIP certificate is expiring soon or has expired you should not delete your Push Credential, instead you should update the Push Credential. More detail is in our IOS SDK quickstart on Github(link takes you to an external page).


On iOS and Andorid SDKs, you can use the [Mobile Preflight APIs]((/docs/voice/sdks/mobile-preflight-test) to test a user's call and network quality before placing a voice call. This preflight test provides a detailed report about the quality of your client's connection with Twilio.

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.