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.
-
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.
-
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.
Note
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
Twillio
let connectOptions = ConnectOptions(token: accessToken) { (builder) in builder.roomName = "existing-room" } let room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)
100ms
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.
Twillio
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)
100ms
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
Twillio
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
Twilio
// 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
Twilio
// 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
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.
Twilio
// 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 } } }
100ms
Use the HMSLocalAudioTrack
and HMSLocalVideoTrack
to mute/unmute tracks
Mute/Unmute Local Audio
-
Mute audio
hmsSDK.localPeer?.localAudioTrack()?.setMute(true)
-
Unmute audio
hmsSDK.localPeer?.localAudioTrack()?.setMute(false)
Mute/Unmute Local Video
-
Mute video
hmsSDK.localPeer?.localVideoTrack()?.setMute(true)
-
Unmute video
hmsSDK.localPeer?.localVideoTrack()?.setMute(false)
Step 8: Leave/End a session
Once you’re done with the call, it’s a good idea to leave the room.
Twillio
twilioVideo.disconnect()
100ms
hmsSDK.leave()
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.