Migration for iOS

This guide is designed to assist developers in migrating their video conferencing applications from Twilio's Programmable Video SDK to the 100ms Video SDK on iOS.

Before we get started here, you are required to create an account on 100ms.

Learn more about the fundamental differences and parities between 100ms and Twilio Programmable Video here.

100ms uses a single SDK for all features, including audio/video conferencing, chat, and recording.

Step 1: Install

Remove the listing for TwilioVideo in the Podfile and run pod install as necessary to remove the Twilio Video SDK.

Install 100ms SDK
You can either use Swift Package Manager or Cocoapods to add 100ms iOS SDK to your project.

  1. Using Swift Package Manager - Add 100ms iOS SDK through Swift Package Manager in Xcode. Use https://github.com/100mslive/100ms-ios-sdk.git as the package source.

  2. Using Cocoapods - Get the HMSSDK via Cocoapods. Add the pod 'HMSSDK' to your Podfile as follows:

    # Podfile platform :ios, '12.0' target 'MyAwesomeApp' do use_frameworks! pod 'HMSSDK' end

    then run pod install --repo-update

Step 2: SDK Authentication

On your auth server, replace your Twilio Video JWT generation logic with the 100ms Auth Tokens generation logic.


Alternatively, you can use the 100ms dashboard to fetch a temporary token that will automatically expire in 24hrs.

Step 3: Initialisation

In order to use 100ms SDK, you must first initialize the SDK instance. This is usually done when your app starts.

There is no equivalent of this in the Twilio Video SDK, so it is important to find the correct place in your app to add initialization logic.

Initialise the 100ms HMSSDK

import HMSSDK class MyMeetingClass { let hmsSDK: HMSSDK // store instance of HMSSDK as a property in your class init() { hmsSDK = HMSSDK.build() // initialize the SDK using the `build()` class function } }

Step 4: Joining a session


let connectOptions = ConnectOptions(token: accessToken) { (builder) in builder.roomName = "existing-room" } let room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)


func joinRoom() { hmsSDK.getAuthTokenByRoomCode("room-code") { token, error in if let token = token { let config = HMSConfig(userName: "John Doe", authToken: token) hmsSDK.join(config: config, delegate: self) } } } override func viewDidLoad() { super.viewDidLoad() joinRoom() }

Step 5: Listening to events

Both SDKs use delegates/listeners to detect and stay in sync with state changes. Replace your Twilio listeners with 100ms SDK delegates.


class YourClass: TVIRoomDelegate { // Add any of the callback functions here as needed. func roomDidConnect(room: Room) { ... } func participantDidConnect(room: Room, participant: RemoteParticipant) { ... } func participantDidDisconnect(room: Room, participant: RemoteParticipant) { ... } func roomDidDisconnect(room: Room, error: Error ? ) { ... } } let room = TwilioVideo.connect(with: connectOptions, delegate: self)


The 100ms SDK sends updates to the application about any change in Room , Peer and Track via the callbacks in HMSUpdateListener. Application need to listen to the corresponding updates.

class MyMeetingClass: HMSUpdateListener { public func on(join room: HMSRoom) { ... } public func on(room: HMSRoom, update: HMSRoomUpdate) { ... } public func on(peer: HMSPeer, update: HMSPeerUpdate) { } public func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer) { } }
/// Whenever a property of peer changes @objc public enum HMSPeerUpdate: Int, CustomStringConvertible { case peerJoined case peerLeft case roleUpdated case nameUpdated case metadataUpdated case handRaiseUpdated case networkQualityUpdated case defaultUpdate } /// Whenever an property of a track changes @objc public enum HMSTrackUpdate: Int, CustomStringConvertible { case trackAdded case trackRemoved case trackMuted case trackUnmuted case trackDescriptionChanged case trackDegraded case trackRestored } /// Whenever an property of a room changes @objc public enum HMSRoomUpdate: Int, CustomStringConvertible { case roomTypeChanged case metaDataUpdated case peerCountUpdated case browserRecordingStateUpdated case serverRecordingStateUpdated case rtmpStreamingStateUpdated case hlsStreamingStateUpdated case hlsRecordingStateUpdated }

Step 6: Video

To check a user’s video status and start or stop their video.

// start camera var cameraSource = CameraSource(delegate: self), let captureDevice = CameraSource.captureDevice(position: .front) cameraSource.startCapture(device: captureDevice, completion: nil) // stop camera cameraSource?.stopCapture() cameraSource = nil

Set up local video preview


// Use CameraSource to produce video from the device's front camera. if let camera = CameraSource(delegate: self), let videoTrack = LocalVideoTrack(source: camera) { // VideoView is a VideoRenderer and can be added to any VideoTrack. let renderer = VideoView(frame: view.bounds) } if let camera = TVICameraCapturer(source: .frontCamera), let videoTrack = TVILocalVideoTrack(capturer: camera) { // TVIVideoView is a TVIVideoRenderer and can be added to any TVIVideoTrack. let renderer = TVIVideoView(frame: view.bounds) // Add renderer to the video track videoTrack.addRenderer(renderer) self.localVideoTrack = videoTrack self.camera = camera self.view.addSubview(renderer) }

Display other user videos


// MARK: RemoteParticipantDelegate /* * In the Participant Delegate, we can respond when the Participant adds a Video * Track by rendering it on screen. */ func didSubscribeToVideoTrack(videoTrack: RemoteVideoTrack, publication: RemoteVideoTrackPublication, participant: RemoteParticipant) { if let remoteView = VideoView.init(frame: self.view.bounds, delegate:self) { videoTrack.addRenderer(remoteView) self.view.addSubview(remoteView) self.remoteView = remoteView } } // MARK: VideoViewDelegate // Lastly, we can subscribe to important events on the VideoView func videoViewDimensionsDidChange(view: VideoView, dimensions: CMVideoDimensions) { self.view.setNeedsLayout() }

100ms SDK provides an easy way to render and manage a user’s video stream. 100ms SDK usesHMSTrack as a the super-class of all the tracks that are used inside HMSSDK. Its hierarchy looks like this -

HMSTrack - AudioTrack - LocalAudioTrack - RemoteAudioTrack - VideoTrack - LocalVideoTrack - RemoteVideoTrack

To display a video track, first get the HMSVideoTrack & pass it on to HMSVideoView using setVideoTrack function. Ensure to attach the HMSVideoView to your UI hierarchy.

// The following code is a sample. // get the video track to be displayed let track = peer.videoTrack // create a view for rendering video track and add to the UI hierarchy let videoView = HMSVideoView() // set the video track of HMSVideoView videoView.setVideoTrack(track) // add the view to UI hierarchy view.addSubview(videoView)

Step 7: Managing Mute/Unmute Local Audio

100ms SDK offers a simpler approach to manage audio.


// For instance, this is how to unpublish the microphone track in the Twilio SDK var room: Room? // Set when connected to a video room var micTrack: LocalAudioTrack? var isLocalMicOn = false { didSet { guard oldValue != isLocalMicOn else { return } if isLocalMicOn { guard let micTrack = LocalAudioTrack(options: nil, enabled: true, name: "mic") else { return } self.micTrack = micTrack room?.localParticipant?.publishAudioTrack(micTrack) } else { guard let micTrack = micTrack else { return } room?.localParticipant?.unpublishAudioTrack(micTrack) self.micTrack = nil } } }


Use the HMSLocalAudioTrack and HMSLocalVideoTrack to mute/unmute tracks

Mute/Unmute Local Audio

  • Mute audio

  • Unmute audio


Mute/Unmute Local Video

  • Mute video

  • Unmute video


Step 8: Leave/End a session

Once you’re done with the call, it’s a good idea to leave the room.





End the session for everyone

On 100ms, allow certain peers to end the call for everyone.

Using 100ms SDK - End the room with hmsSdk.endRoom

endRoom takes three parameters.

  • reason: Optional message you want to pass along the end room notification to other peers

  • lock: Whether you want to prevent anyone from rejoining the room. If false, they will be allowed to enter the room again if the client called join. If this is false, they will not able to join this room again.

  • completion handler: Lets you know whether the end room operation executed. was ended successfully or not.

    hmssdk.endRoom(lock: false, reason: "Meeting is over") { success, error in if (success) { // pop to previous screen } }

REST APIs and Webhooks

100ms has a full suite of REST APIs and webhooks.

The REST APIs will allow you to perform all server side CRUD operations on rooms, sessions, live streams, recordings, transcription, and more.

Have a suggestion? Recommend changes ->

Was this helpful?