migration-guide-twilio-to-agora-ios

Migration Guide from Twilio to Agora – iOS edition

Agora’s voice, video and live broadcasting software all run on a Software Defined Real-Time Network (SD-RTN™), which is a realtime transmission network built by Agora and is the only network infrastructure specifically designed for realtime communications 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 or live broadcasting needs. Another may be pricing. Whatever the need may be, the following 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 completely different set of required methods, and an entirely new feel.

Adoption Guide

To drive adoption, Agora is offering this guide. To simplify the adoption process, here are the three primary codebases:

Adoption

Just as TokBox’s integration is heavily dependent upon delegates, so too is Twilio. Twilio’s TwilioVideo SDK requires implementation of four delegates, which is nearly the same number of delegates TokBox’s integration requires: TVIRoomDelegateTVIRemoteParticipantDelegateTVIVideoViewDelegateTVICameraSourceDelegate, each of which has an inordinately large number of required methods. As is the case with TokBox, adoption of the Agora iOS SDK proceeds from a change in architecture. Agora’s iOS SDK, however, is an architecture based upon the singleton design pattern.

At Agora we empathize web developers such as Dzung Nguyen or Anand Nimje, who look for simplicity in development so that our iOS SDK is designed in accordance with popular development sentiments in mind. Many developers such as Dzung Nguyen, for instance, claim the Singleton pattern in iOS to be “the most common and easiest-to-implement design pattern.” Others such as Anand Nimje, whose describes the design pattern as “very popular in development”, says it is a “[very simple, common and easy to use.”

What is the singleton design pattern?

A singleton is a design pattern much like the all too familiar Model View Controller is a design pattern, except it is a pattern whose single instance returns no matter which application resource makes the request. It provides a global point of access to its available methods. 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 or broadcasting.

In this adoption guide, you learn how to singlehandedly replace Twilio’s TwilioVideo with Agora’s AgoraRtcEngine_iOS to power live voice, video or 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 AppDelegate.swift:

let AppID = ""

Step Two

The next step requires replacing both the Twilio’s TwilioVideo pod as well as the imports. In the pod file add AgoraRtcEngine_iOS in place of theTwilioVideo pod in the Podfile. At the top of the ViewController file replace the import TwilioVideo with AgoraRtcEngineKit. Run pod update and install.

Step Three

The next step requires replacing the four Twilio delegates with an instance of Agora’s singleton. At the bottom of the ViewController, remove the four extensions: TVIRoomDelegateTVIRemoteParticipantDelegateTVIVideoViewDelegateTVICameraSourceDelegate. 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)
    agoraKit.enableWebSdkInteroperability(true)
}

Here you pass your AppID into the sharedEngine method, assigning the delegate as “self”. While enabling web SDK interoperability is optional, enable it here so that you can use it for testing with the web. 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!

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

Step Four

To replace Twilio’s local/remote functionality with Agora’s local and remote video setups, remove the publisher/subscriber methods:

  • setupRemoteVideoView()
  • connect()
  • disconnect()
  • prepareLocalMedia()
  • startPreview()

With these five or any other relevant Twilio specific method already removed, you add three parts for enabling video, setting up the video, and configuring the canvas or video display through a delegate, which is standard in iOS.

  • Add a function now for enabling video:
func setupVideo() {
    agoraKit.enableVideo()
    agoraKit.setVideoEncoderConfiguration(AgoraVideoEncoderConfiguration(size: AgoraVideoDimension640x360, frameRate: .fps15, bitrate: AgoraVideoBitrateStandard, orientationMode: .adaptative) ) // Default video profile is 360P}

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.

  • Add a function for setting up local video:
func setupLocalVideo(uid: UInt) {
        
        let videoView = UIView()
        videoView.tag = Int(uid)
        videoView.backgroundColor = UIColor.orange
        
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = uid
        videoCanvas.view = videoView
        videoCanvas.renderMode = .hidden
        agoraKit.setupLocalVideo(videoCanvas)
        
        stackView.addArrangedSubview(videoView)
        
    }

The local video is, as explained earlier, Alice’s device camera capturing video of her and upon joining a channel, as you will see later, it streams into Bob’s phone as a remote video.

  • Add an extension to ViewController for the AgoraRtcEngineDelegate to configure the canvas or video:
func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoFrameOfUid uid: UInt, size: CGSize, elapsed: Int) {let videoView = UIView()
        videoView.tag = Int(uid)
        videoView.backgroundColor = UIColor.purple
        
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = uid
        videoCanvas.view = videoView
        videoCanvas.renderMode = .hidden
        agoraKit.setupRemoteVideo(videoCanvas)
        
    }
    
    internal func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid:UInt, reason:AgoraUserOfflineReason) {
        
        guard let view = stackView.arrangedSubviews.first(where: { (view) -> Bool in
            return view.tag == Int(uid)
        }) else { return }
        
        stackView.removeArrangedSubview(view)
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didVideoMuted muted: Bool, byUid uid: UInt) {
        //
    }

Agora’s delegate method firstRemoteVideoFrameOfUid kicks off the reception of another user’s local video or, put in another way, Alice’s local video on Bob’s device as a remote video. It is the method designed to handle the first frame coming out of a remote stream! If that UID drops off, didOfflineOfUid handles their departure and its consequences for the call. Finally, add a call to setupVideo() in viewDidLoad().

Step Five

Last but not least is joining a channel. You join a user to a channel with .joinChannel, a single method in the Agora iOS SDK that takes a value for a parameter called byToken, a value for a channelId, a value for info, as well as an uid:

func joinChannel() {
    agoraKit.setDefaultAudioRouteToSpeakerphone(true)
    agoraKit.joinChannel(byToken: nil, channelId: “demoChannel1”, info:nil, uid:0){[weak self] (sid, uid, elapsed) -> Void in
    // Join channel “demoChannel1”
    }
   UIApplication.shared.isIdleTimerDisabled = true
}

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 less than five steps. Now it should be easy to simulate fully a large scale adoption with Agora. The changes that need to be made are 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. Accordingly, you probably have a few questions now about product design with respect to SDKs.

Product Design

The SD-RTN™, for instance, provides:

  1. Global network coverage
  • Covers 200+ countries and regions
  • Covers dozens of small and medium telecommunication providers in China

2. Mass access capability

  • Supports multiple intelligent terminal access
  • A single channel can support a million people online at the same time

3. QoS (Quality of Service) capability enhancement

  • Prevents network congestion in advance
  • Weak network anti-loss guarantee

4. QoS-based dynamic routing

  • Comprehensive assessment of network resources
  • QoS optimal path guarantee

5. SLA (Service Level Agreement) guarantee

  • 7 × 24 support, including ticketing system/IM/community
  • One-to-one VIP service

6. Global network reliability

  • Global network availability at 99.999%
  • Invisible core business, such as anti-DDoS

7. Compatibility and Interoperability

  • Support for 6000+ devices
  • Support for mainstream web browsers, including Google Chrome, Safari, and Firefox
  • Support for iOS, Android, the Web, Windows, macOS, Linux, CoCos, Unity, and so on

8. UDP (User Datagram Protocol) optimizationOptimizes multiple private protocols based on the UDPSelf-developed audio and video codecs

  • Efficient use of network resources
  • Self-developed SOLO and NOVA codecs

9. Anti-packet-loss optimization

  • Algorithm for optimizing anti-packet-loss mechanism under weak network conditions
  • Audio anti-packet-loss rate of 70%

With these features enabled through the SD-RTN™ natively both in the iOS as well as the Android mobile SDKs Agora provides a powerful, competitive source of live voice, video or broadcasting for your needs.

Runtime Comparison

Test it out. Although most product specialists take an ad-hoc approach to field-test their SDKs under different conditions (if at all), there is another way. Wouldn’t it be great to complete a runtime comparison? How does TokBox’s video streaming compare to Agora’s SD-RTN™ in terms of multiple levels of packet degradation? Apple’s Network Link Conditioner is a really useful utility that allows macOS and iOS devices to accurately and consistently simulate adverse networking environments (i.e., 100% Loss, 3G, DSL, EDGE, High Latency DNS, LTE, Very Bad Network, WiFi,
WiFi 802.11ac) that simulate packet degradation, or, check out the blog on successively degraded network conditions with customized packet loss.