Skip to content
Migration Guide from Twilio to Agora: iOS Edition Featured

Migration Guide from Twilio to Agora: iOS Edition

By Author: Jonathan Fotland In Developer

Agora’s voice, video, and live-broadcasting software runs on a Software Defined Real-Time Network (SD-RTN™), which is a real-time transmission network built by Agora and the only network infrastructure specifically designed for real-time engagement in the world. All voice and video services provided by the Agora SDK are deployed and transmitted through the Agora SD-RTN™.

The Agora SD-RTN™ may be one motivation for adopting the Agora iOS SDK for all of your voice, video, and live-broadcasting needs. Or you may be looking for ease of use or lower latency. Whatever the need may be, this guide details how a generically functional app with a working Twilio video integration may be disintegrated to provide essentially the same functionality but on a totally different infrastructure, with a smaller set of required methods, and an entirely new feel.

Agora offers this guide to drive adoption. To make things straightforward, we will be using the Twilio Quickstart sample app as a baseline. Here is the codebase for the sample application.


Twilio’s integration is heavily dependent upon delegates. Twilio’s TwilioVideo SDK requires implementation of four delegates: TVIRoomDelegate, TVIRemoteParticipantDelegate, TVIVideoViewDelegate, and TVICameraSourceDelegate. Each has an inordinately large number of required methods. The Agora iOS SDK, however, is based on the singleton design pattern. While Agora does use delegates, only the AgoraRtcEngineDelegate is required, and you need to implement only the methods relevant to your application. As such, you can get your application up and running with significantly less boilerplate, and need only implement the callbacks your application specifically needs. Nor do you need to worry about managing multiple delegates from many disparate pieces, and making sure to maintain those connections as users join and leave.

What is the Singleton Design Pattern?

Much like the Model View Controller design pattern, the singleton design pattern is a way of structuring your code for a specific purpose. A singleton is an instance where the same object is returned no matter which application makes the request. It provides a global point of access to its available methods. As stated in the Apple Design Documentation:

“A singleton class returns the same instance no matter how many times an application requests it.”

Used in situations where a single point of control is desirable, a singleton is great for services like those offered by Agora in the CPaaS market such as live voice, video, and broadcasting.

In this guide, you learn how to easily replace Twilio’s TwilioVideo with Agora’s AgoraRtcKit to power live voice, video, and broadcasting integrations.

Step One

The first step to replacing Twilio’s delegate design pattern with Agora’s singleton design pattern is to create an easily accessible variable in the


let AppID = ""

Step Two

The next step requires replacing the Twilio’s TwilioVideo pod as well as the imports. In the Podfile add AgoraRtcEngine_iOS in place of the TwilioVideo pod. At the top of the ViewController file replace the import TwilioVideo with AgoraRtcKit. In Terminal, run pod install to install the library.

Step Three

Step three requires replacing the four Twilio delegates with an instance of the Agora singleton. At the bottom of the ViewController, remove the four extensions: TVIRoomDelegate, TVIRemoteParticipantDelegate, TVIVideoViewDelegate, and TVICameraSourceDelegate. Also delete the room, camera, localVideoTrack, localAudioTrack, and remoteParticipant variables. Change the remoteView and previewView variables to be UIView objects instead of Twilio’s VideoView.

With these four delegates removed, create a function for initializing an instance of the Agora singleton:

func initializeAgoraEngine() {
    agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: AppID, delegate: self)

Here you pass your AppID into the sharedEngine method, assigning the delegate as “self.” With the initialization function setup, make sure to call the function in viewDidLoad. Finally, make sure to create a property at the top of your ViewController file for initialization:

var agoraKit: AgoraRtcEngineKit!

That is essentially all you need to completely replace Twilio’s delegate-heavy design pattern with Agora’s singleton design pattern. With the design pattern of the app’s architecture transformed, in the next steps you replace Twilio’s local and remote functionality with Agora’s local and remote video setups.

Step Four

  • Add a function for enabling video:

Agora’s AgoraVideoEncoderConfiguration is designed primarily to empower developers with the ability to set a video dimension, a frame rate, a bitrate, and an orientation so that you can control how to deliver your video. Make sure you call this function from your viewDidLoad as well.

  • Replace the startPreview function with the following:

This sets up the local video with Agora. The local video is Alice’s device camera capturing video of her. On joining a channel (as you will see later) it streams into Bob’s phone as a remote video. Agora uses an AgoraRtcVideoCanvas attached to a simple UIView, so make sure that previewView is changed from a Twilio VideoView to a UIView in both the ViewController and the Storyboard.

  • Add an extension to ViewController for the AgoraRtcEngineDelegate to configure the canvas or video:

Replace the initialization of remoteView in setupRemoteVideoView with the following:

Leave the rest of the function as is. You can now delete renderRemoteParticipant, renderRemoteParticipants, and cleanupRemoteParticipant. You can also remove prepareLocalMedia.

Agora’s delegate method didJoinedOfUid kicks off the reception of another user’s local video or, to put it another way, Alice’s local video on Bob’s device as a remote video. If that UID drops off, didOfflineOfUid handles their departure and its consequences for the call.

Step Five

The final step is joining a channel. You join a user to a channel with .joinChannel, a single method in the Agora iOS SDK that takes a token for a parameter called byToken, a channel name for channelId, and an optional info field, as well as a uid. Replace the contents of the connect function:

Other Features

You can replace a few other functions with Agora functionality.

  • disconnect():
@IBAction func disconnect(sender: AnyObject) {


  • flipCamera():
@objc func flipCamera() {
  • toggleMic():

These features are all very simple with the Agora API.


There you go! If you programmed your twilioDisintegrationTool’s xcworkspace according to the instructions in this guide, your code should run as well as, if not better, than the code in the agoraIntegrationTool. If so, then you have successfully adopted Agora! Congratulations! Welcome to the benefits of the Agora SD-RTN™!

Although it would be impossible to account for all of the different integrations, you should note that you replaced all of the salient generic features of Twilio with those of Agora in only five steps. Now it should be easy to simulate fully a large-scale adoption with Agora. The necessary changes include the shift in design pattern architecture, as well as the new concepts such as local vs. remote video (as opposed to publish or subscribe), together with joining a channel.

Additional Resources

You can find the completed project here. For further reading and details on how to implement more specific features of the Agora engine, you can take a look at our documentation, join our Slack community, or email us at