Manage Roles - iOS
Roles with VideoSDK
When doing interactive live streaming, maintaining the role of users is quite important. To help manage these roles better, VideoSDK allows a participant to join with one of these modes:
1. SEND_AND_RECV When a participant is joining with mode set to SEND_AND_RECV, that participant can send their own media and receive the media of other participants, and can also interact with them using the features like chat, poll etc.
2. SIGNALLING_ONLY When a participant is joining with mode set to SIGNALLING_ONLY, that participant neither sends nor receives media. They can still interact with other participants using chat, polls etc.
3. RECV_ONLY When a participant is joining with mode set to RECV_ONLY, that participant can receive the media of other participants but cannot send their own. They can also interact with other participants using chat, polls etc.
Mode.CONFERENCE and Mode.VIEWER were removed in 4.0.0. Use SEND_AND_RECV instead of CONFERENCE, and SIGNALLING_ONLY instead of VIEWER.
This image is for educational purposes

When to use the Roles?
1. Simple Adaptive Streaming
-
Simple Adaptive Streaming (SAS) is a type of livestreaming that requires minimal interaction between the host and viewers.
-
It is particularly useful for events with a large number of viewers who prefer not to engage with the host.
-
In SAS, each speaker attends a VideoSDK room in
SEND_AND_RECVmode, while viewers can simply watch the livestream using theplaybackHlsUrlorlivestreamUrl. Unlike the speakers, viewers do not need to join the room inSEND_AND_RECVorSIGNALLING_ONLYmode.playbackHlsUrl- Live HLS with playback supportlivestreamUrl- Live HLS without playback support
This video is for educational purposes
2. Adaptive Streaming with increased engagement
-
If you're looking to increase engagement with your audience during a live streaming event, consider using Adaptive Streaming technology. With this approach, you can incorporate interactive features such as polls and conversations, and give viewers the ability to join and leave the livestream as the host decides.
-
To set this up, have all speakers join as
SEND_AND_RECVmode participants, while the audience joins asSIGNALLING_ONLYmode participants. This way, everyone can participate in the interactive elements of the live stream and create a more dynamic and engaging experience for all.
This video is for educational purposes
Using roles
When you initialize the Room, you can set the mode of Participant. VideoSDK.createRoom(...) throws ERROR_INVALID_PARAMETER for an empty room ID or token, so call it with try.
- Swift
class LiveStreamViewController: ObservableObject {
init(roomId: String, role: UserRole) {
//...
initializeRoom()
}
// MARK: - Room Initialization
func initializeRoom() {
do {
room = try VideoSDK.createRoom(
roomId: roomId,
token: AUTH_TOKEN,
participantName: "John doe",
micEnabled: self.isMicOn,
camEnabled: self.isCamOn,
mode: .SEND_AND_RECV, // allowed: .SIGNALLING_ONLY, .RECV_ONLY & .SEND_AND_RECV
multiStream: true
)
} catch {
print("Setup failed: \(error)")
return
}
// Add event listeners and join the live stream
room?.addEventListener(self)
//...
}
}
Getting Participant Mode
You can identify the participant's role by using mode property from Participant class.
- Swift
class LiveStreamViewController: ObservableObject {
//...
func printLocalParticipantMode() {
if let participantMode = room?.localParticipant.mode {
print("Local participant's mode: \(participantMode.rawValue)")
}
}
//...
}
Changing Participant's Mode
Let's say you are hosting a livestream and you want one of your viewers to join the livestream with you. In this case the viewer changes their own mode using the changeMode() of the Room class. changeMode() changes only the mode of the participant who calls it, so the host first sends the viewer a request, as shown in Invite Guest on Stage.
- Swift
class LiveStreamViewController: ObservableObject {
//...
func changeToSendReceiveMode() {
Task {
do {
// change mode to SEND_AND_RECV
try await room?.changeMode(.SEND_AND_RECV)
} catch let error as VideoSDKError where error == .ERROR_ALREADY_IN_REQUESTED_STATE {
// already in SEND_AND_RECV mode
} catch {
print("Could not change mode: \(error)")
}
}
}
func changeToSignallingOnlyMode() {
Task {
do {
// change mode to SIGNALLING_ONLY
try await room?.changeMode(.SIGNALLING_ONLY)
} catch let error as VideoSDKError where error == .ERROR_ALREADY_IN_REQUESTED_STATE {
// already in SIGNALLING_ONLY mode
} catch {
print("Could not change mode: \(error)")
}
}
}
//...
}
changeMode()isasync throws, so call it withtry awaitinside aTask.- It throws
ERROR_ALREADY_IN_REQUESTED_STATEwhen the participant is already in that mode. - Switching to
SIGNALLING_ONLYorRECV_ONLYstops the participant's screen share and turns off their mic and camera. - Switching back to
SEND_AND_RECVturns the mic and camera back on if they were on before the switch. A participant who joined inSIGNALLING_ONLYorRECV_ONLYgets, on their first switch, the mic and camera thatmicEnabledandcamEnabledofcreateRoom()asked for. UseonStreamEnabledto see what came back, and callunmuteMic()orenableCam()only for a device that stays off. - Every participant receives
onParticipantModeChanged(participantId:mode:)when the mode changes.
API Reference
The API references for all the methods utilized in this guide are provided below.
Got a Question? Ask us on discord

