
Migration Guide from Twilio to Agora: iOS Edition
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.
Overview
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
ViewController.swift
:
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 theAgoraRtcEngineDelegate
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) {
agoraKit.leaveChannel(nil)
}
flipCamera():
@objc func flipCamera() {
agoraKit.switchCamera()
}
toggleMic()
:
These features are all very simple with the Agora API.
Run
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 devrel@agora.io.