Menu

Expand
Rate 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

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.

Debugging

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

    /* Obj-C */
    [VoiceClient setLogLevel:TVOLogLevelVerbose];
    /* Swift */ 
    VoiceClient.logLevel = .verbose

voice_ios_sdk_debug1

voice_ios_sdk_debug2

Push registration and lifecycle

Register for push notifications on every application.

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.

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

It's important to unregister from push notifications using the SDK's unregister methods (iOS SDK method, Android SDK method) 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.

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

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.

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

Android:

  1. React to the new device token (See See Android SDK Quickstart example)
    public void onNewToken(String token) {
            super.onNewToken(token);
            Intent intent = new Intent(Constants.ACTION_FCM_TOKEN);
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        }
  2. Re-register for call invites with new token (See Android SDK Quickstart example)
    case Constants.ACTION_FCM_TOKEN:
                        registerForCallInvites();
                        break;

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

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

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

Restrictive networks may fail unless ICE servers are provided via Connect Options or Accept Options. ICE servers can be obtained from Twilio 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.

// Android
ConnectOptions.Builder builder = new
ConnectOptions.Builder(accessToken);

builder.enableIceGatheringOnAnyAddressPorts(true);
// iOS
let connectOptions = ConnectOptions(accessToken: accessToken) { builder in
        builder.params = [“foo”: “bar”]
        builder.uuid = uuid
        builder.enableIceGatheringOnAnyAddressPorts = true
     }

let call = TwilioVoiceSDK.connect(options: connectOptions, delegate: self)

AccessTokens

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.
Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

        
        
        

        Thank you for your feedback!

        Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

        Sending your feedback...
        🎉 Thank you for your feedback!
        Something went wrong. Please try again.

        Thanks for your feedback!

        thanks-feedback-gif