Calls SDKs iOS v1
Calls SDKs iOS
Calls SDKs
iOS
Version 1

Group call

Copy link

This page explains the key functions of group call consisting of how to create a room and how a user can participate in a group call by entering and exiting a room from your app.


Create a room

Copy link

You can choose to create a room that supports up to 6 participants with video or a room that supports up to 100 participants with audio. When a user creates a room in your app, the room’s status becomes OPEN and a ROOM_ID is generated.

You can create a room by setting the room type by using the Type property and the createRoom() method as shown below.

let roomType = RoomType.smallRoomForVideo
let params = RoomParams(roomType: roomType)
SendBirdCall.createRoom(with: params) { room, error in
    guard let room = room, error == nil else { return } // Handle error.
    // room is created with a unique identifier room.roomId.
}

List of properties

Copy link
Property nameDescription

type

Type: RoomType
Specifies the type of the room. Valid values are limited to the following:
- smallRoomForVideo: type of a room that supports audio and video, can have up to 6 participants.
- largeRoomForAudioOnly: type of a room that only supports audio, can have up to 100 participants.


Retrieve a list of rooms

Copy link

You can retrieve a list of rooms by using the RoomListQuery and the following table shows all supported filters for the RoomListQuery to search for specific rooms you want to retrieve.

List of filters

Copy link
NameFilters...

setRoomIds

Query results to include rooms that match the specified room IDs.

setType

Query results to include rooms with the specified room type.

setState

Query results to include room with the specified room state.

setRangeForCreatedAt

Query results to include rooms that were created between the specified range of time.

setRangeForCurrentParticipantCount

Query results to include rooms with the specified range of numbers for current participants.

setCreatedByUserIds

Query results to include rooms that were created by specified user IDs.

You can specify the above filters as shown below:

let params = RoomListQuery.Params()
            .setType(.largeRoomForAudioOnly)
            .setLimit(50)
            .setState(.open)
            .setRangeForCurrentParticipantCount(3...)
            .setCreatedByUserIds([USER_ID1, USERID2])
            .setRangeForCreatedAt(..<Date())

To retrieve a list of rooms, call the RoomListQuery.next(completionHandler:) method.

let query = SendBirdCall.createRoomListQuery(with: params)
if query?.hasNext == true, query?.isLoading == false {
    query?.next{ rooms, error in
        guard let rooms = rooms, error == nil else {
            // Error has occurred.
            return
        }
        ...
    }
}

When a list of rooms is retrieved, you can show the list to a user and allow the user to select a room they want to enter.

rooms.first?.enter(with: .init()) { error in
    // User has entered the room.
}

Note: The room data returned from the query is not updated unless the user has entered the room. To update the details about a room, call the SendBirdCall.fetchRoom(by:completionHandler:) method.


Enter a room

Copy link

A user can search a room with a specific room ID to participate in a group call at any time. When a user enters a room, a participant is created with a unique participant ID to represent the user in the room.

To enter a room, you must acquire the room instance from Sendbird server with the room ID. To fetch the most up-to-date room instance from Sendbird server, use the SendBirdCall.fetchRoom(by:completionHandler:) method. Also, you can use the SendBirdCall.getCachedRoom(by:) method that returns the most recently cached room instance from Sendbird Calls SDK.

SendBirdCall.fetchRoom(by: ROOM_ID) { room, error in
    guard let room = room, error == nil else { return } // Handle error.
    // room with the identifier ROOM_ID is fetched from the Sendbird server.
}

let cachedRoom: Room? = SendBirdCall.getCachedRoom(by: ROOM_ID)
// Returns the most recently cached room from the SDK.
//If there is no such room with the given room ID, nil is returned.

Note: A user can enter the room using multiple devices or browser tabs. Entering from each device or browser tab will create a new participant.

Once the room is retrieved, call the enter(with:completionHandler:) method to enter the room.

let params = Room.EnterParams(isVideoEnabled: true, isAudioEnabled: true)
room.enter(with: params) { error in
    guard error == nil else { return } // Handle error.
    // User has successfully entered room.
}

Kick out siblings of the user

Copy link

In a room, a single user can enter the same room multiple times as a different participant. However, if you want to prevent the user from entering the room simultaneously using different mobile devices and web browsers, you can kick out siblings of the user by calling room.enter(). It will result the user to be the unique participant remaining in the room.

let params = Room.EnterParams(isVideoEnabled: true, isAudioEnabled: true, kickSiblings: true)
room.enter(with: params) { error in
    guard error == nil else { return } // Handle error.

    // User has successfully entered room and any other participants of the same user will be kicked out.
}

Note: Share the room ID with other users for them to enter the room from the client app.


Exit a room

Copy link

To leave a room, call room.exit(). On the room delegates of the remaining participants, the RoomDelegate.didRemoteParticipantExit(_:) method will be called.

do {
    try room.exit()
    // participant has exited the room successfully.
} catch {
    // SBCError.participantNotInRoom is thrown because participant has not entered the room.
}

Delete a room

Copy link

If you would like to delete a room, you can call the delete() method. When this method is called successfully, the room will be permanently deleted, all participants in the room will be exited automatically, and the media connection will be stopped. Any participants in the room can delete the room.

room.delete { error in
    guard error == nil else { return } // An error occurred while deleting the room.

    // The room was successfully deleted.
}

Handle events in a room

Copy link

A user can receive events of a room that they are currently participating. Users will be notified when other participants enter or leave the room, change their media settings or when the room is deleted.

Add event delegate

Copy link

Add an event delegate for the user to receive events that occur in a room that the user joins as a participant.

room.addDelegate(myClass, identifier: UNIQUE_IDENTIFIER)

class MyClass: RoomDelegate {
}

Receive events on enter and exit

Copy link

When a participant joins or leaves the room, other participants in the room will receive the following events.

class MyClass: RoomDelegate {
    // Called when a remote participant has entered the room.
    func didRemoteParticipantEnter(_ participant: RemoteParticipant) { }

    // Called when a remote participant has exited the room.
    func didRemoteParticipantExit(_ participant: RemoteParticipant) { }
}

Receive events on media setting

Copy link

A local participant can change the media settings such as muting their microphone or turning off their camera by using muteMicrophone() or stopVideo(). Other participants will receive event delegates that notify them of the corresponding media setting changes.

class MyClass: RoomDelegate {
 // Called when audio settings of a remote participant have been changed.
    func didRemoteAudioSettingsChange(_ participant: RemoteParticipant) { }

    // Called when video settings of a remote participant have been changed.
    func didRemoteVideoSettingsChange(_ participant: RemoteParticipant) { }
}

Receive events on local participant's connection status

Copy link

A local participant may lose their media stream in the room if their network connection is unstable. The didLocalParticipantDisconnect event delegate will be sent to the local participant when they are disconnected. Once the media stream is reconnected, the didLocalParticipantReconnect event delegate will be sent.

You can use the received events to alert the local participants to switch to a more stable network or take other appropriate actions to stay connected to the room. Implement the code below to receive events on local participant's connection status.

class MyClass: RoomDelegate {
    // Called when local participant's network is interrupted and the local participant is disconnected from the server.
    func didLocalParticipantDisconnect(_ participant: LocalParticipant) { }

    // Called when local participant's network connection is restored and the local participant is reconnected to the server.
    func didLocalParticipantReconnect(_ participant: LocalParticipant) { }
}

Receive events on deleted room

Copy link

To delete a room through Calls Platform API, see Delete a room in the Calls API documentation. When a room is deleted, participants in the room will receive the following event.

class MyRoom: RoomDelegate {
    // Called when the room has been deleted.
    func didDelete() { }
}

Remove event delegate

Copy link

To stop receiving events about a room, remove the registered delegates as shown below:

// Removes registered delegate that has the matching identifier.
room.removeDelegate(identifier: UNIQUE_IDENTIFIER)

// Removes all registered delegates to stop receiving events about a room.
room.removeAllDelegates()

Invite users with notifications

Copy link

You can let users into a room by sharing the room ID or by sending invitation to certain users as a notification. Invitees can accept or decline your invitations and you can also cancel them.

Invite a user

Copy link

First, you need to be in the room to which you would like to invite other users. Follow the steps in Create a room and Enter the room to invite other users.

Send an invitation with the invitee's user ID and the room ID to the user you want to invite. When the invitation is sent successfully, the invited user will receive a notification on their device notifying them that you've invited them to join a room.

In order to send push notifications, you must configure the push notification certificates on Sendbird Dashboard and upload the device's push tokens after you authenticate. Refer to our push notifications guide for more information.

let inviteeId: String = ""
room.sendInvitation(invitee: inviteeId) { invitation, error in
    guard error == nil else { return } // An error occurred while sending an invitation.

    // Successfully sent an invitation to the invitee.
}

Show the invitation to the invitee

Copy link

When a user is invited, they will receive a notification that shows information about who invited them to which room. To show such information, you must pass the push notification to Sendbird Calls SDK as shown below.

class AppDelegate {
    ...

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        SendBirdCall.application(application, didReceiveRemoteNotification: userInfo)
    }
}

When the push notification is passed to the Calls SDK, the didReceiveInvitation delegate will be called and the option will automatically be shown to the invitee to accept or decline the invitation.

@main
class AppDelegate: UIResponder, UIApplicationDelegate, SendBirdCallDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let applicationId: String = <#YOUR_APPLICATION_ID#>
        SendBirdCall.configure(appId: applicationId)
        SendBirdCall.addDelegate(self, identifier: String(describing: Self.self))

        ...

        return true
    }

    func didReceiveInvitation(_ invitation: RoomInvitation) {
        // Did receive an invitation from invitation.inviter.
    }
}

Cancel an invitation

Copy link

If you would like to cancel an invitation that you sent, follow the code below. When you cancel the invitation, the invited user won't be able to enter the room when they open the notification.

let inviteeId: String = ""
room.sendInvitation(invitee: inviteeId) { invitation, error in
    guard let invitation = invitation,  error == nil else { return } // An error occurred while sending an invitation.

    invitation.cancel { error in
        // Cancelled the invitation sent to the invitee.
    }
}

Accept or decline the invitation

Copy link

When the invited user accepts or declines the invitation, the user who invited them will be notified. You can add UI updates to let the inviter know whether the user they invited accepted or declined the invitation.

func didReceiveInvitation(_ invitation: RoomInvitation) {
    // Accept an invitation.
    invitation.accept { error in
        // Invitation was accepted with error: \(error)
    }

    // Decline an invitation.
    invitation.decline { error in
        // Invitation was accepted with error: \(error)
    }
}

Call room.Enter() to let the invitee enter the room once the invitee accepts the invitation. After the invitee enters and gets connected to the room, the inviter and invitee will be able to view each other's media stream.

List of event delegates

Copy link
Event DelegateDescription

wasInvitationAccepted

Invoked when the invitee accepts the invitation to enter the room.

wasInvitationDeclined

Invoked when the invitee declines the invitation to enter the room.


Manage custom items

Copy link

With custom items for group calls, you can store additional information as key-value pairs to a room in the Room object. Custom key-value items are saved as a [String: String] dictionary and can be updated or deleted as long as the room status is OPEN. Information related to customer service, refund, or inquiry can be added as custom items for better user experience.

When a room is created, users can add custom items in RoomParams as [String: String] dictionary type. By default, the customItems is an empty dictionary.

let customItems = [“key”: “value1”, “key2”: “value2”]
let params = RoomParams(roomType: .smallRoomForVideo, customItems: customItems)
SendBirdCall.createRoom(with: params) { room, error in
    // Set up delegates to receive events.
 }

Update and delete

Copy link

Custom items can be updated or deleted as long as the room status is OPEN. If a new custom item has the same key as the existing custom item, the new item will update the value of the existing item. A new item with a new key will be added to the list of custom items. You can update existing custom items by calling the room.updateCustomItems(customItems:completionHandler:).

You can delete custom items by calling the room.deleteCustomItems(customItemKeys:completionHandler:) with the list of keys that you want to delete from the list of custom items.

let customItems = [“key1”: “value3”]
room.updateCustomItems(customItems: customItems, completionHandler: { customItems, updatedKeys, error in
    // Custom items with matching keys in updatedKeys have been updated in the customItems.
})

let keys = [“key1”]
room.deleteCustomItems(customItemKeys: keys, completionHandler: { customItems, deletedKeys, error in
     // Custom items with matching keys in deletedKeys have been deleted from customItems.
})

Receive events

Copy link

A participant in a room can receive events from Sendbird server when other participants update or delete custom items in the room. Implement the didUpdateCustomItems(updatedKeys:) and the didDeleteCustomItems(deletedKeys:) from the RoomDelegate to receive events from other participants. Each event contains the list of keys of the changed custom items, such as updatedKeys or deletedKeys.

Custom items can be modified and the events are delivered to the RoomDelegate only when the room's status is OPEN and there are participants in the room. To check the custom items that had been changed for ended or ongoing calls in a room, you can use the Calls API or room.fetchCustomItems(completionHandler:).

class MyClass: RoomDelegate {
  func didUpdateCustomItems(updatedKeys: [String]) {
      // Custom items with updatedKeys have been updated in the target room.
  }
  func didDeleteCustomItems(deletedKeys: [String]) {
      // Custom items with deletedKeys have been deleted in the target room.
  }
}

Interact within a room

Copy link

Participant’s actions, such as turning on or off their microphone or camera, in a room are handled by the participant objects.

To control the media of the local user, you can use the following methods from the Room.localParticipant object:

// Mutes the local participant's microphone.
room.localParticipant.muteMicrophone()

// Unmutes the local participant's microphone.
room.localParticipant.unmuteMicrophone()

// Stops the local participant's video.
room.localParticipant.stopVideo()

// Starts the local participant's video.
room.localParticipant.startVideo()

// Switches between the front and back camera.
room.localParticipant.switchCamera(completionHandler: ErrorHandler)

Display video view

Copy link

When there is a participant in the room, a media stream is established between a participant and Sendbird server to support group calls. You can configure the user interface for participants in a room by using the properties in Participant.

Receive media stream

Copy link

The following is the process of how participants can send and receive media streams in a room:

Step 1: To send a media stream, a participant who would like to send its media stream has to be connected to Sendbird server.

Step 2: To receive a media stream, a participant who would like to receive a media stream from another participant has to be connected to the media server. Once connected, the didRemoteParticipantStreamStart(_:) method will be invoked which notifies that the receiving media stream has started.

Step 3: Add a view to show the received media stream.

class MyClass: RoomDelegate {
    // Called when a remote participant is connected to the media stream and starts sending the media stream.
    func didRemoteParticipantStreamStart(_ participant: RemoteParticipant) { }
}

You can receive a video stream from a participant by configuring the videoView property as shown below:

@IBOutlet weak var participantVideoView: UIView?

// Create SendBirdVideoView.
let participantSendBirdVideoView = SendBirdVideoView(frame: self.participantVideoView?.frame ?? CGRect.zero)
self.participantVideoView?.embed(participantSendBirdVideoView)

// Configure participants video view.
// participant: Participant
participant.videoView = participantSendBirdVideoView

Manage video layout

Copy link

You can show participants in gallery view as they enter or exit the room by using UICollectionView which dynamically changes views. You can set the number of items to be the count of room.participants and the custom cells to represent each participant.

When the below methods in RoomDelegate are called, information for room.participants gets updated and the number of items are changed accordingly. To have the custom cells added or removed, you need to call UICollectionView.reloadData() for the delegate methods.

List of methods

Copy link
MethodDescription

didRemoteParticipantEnter(_ participant: RemoteParticipant)

Invoked when a remote participant has entered a room.

didRemoteParticipantExit(_ participant: RemoteParticipant)

Invoked when a remote participant has exited a room.

didRemoteParticipantStreamStart(_ participant: RemoteParticipant)

Invoked when a remote participant has started media streaming.

didRemoteAudioSettingsChange(_ participant: RemoteParticipant)

Invoked when a remote participant's audio settings have changed.

didRemoteVideoSettingsChange(_ participant: RemoteParticipant)

Invoked when a remote participant's video settings have changed.

Show default image for user

Copy link

If a participant is not connected to the call or has turned off their video, you can set a default image to show on the screen for that participant. Otherwise, it will be shown as black to other participants. To check whether a participant has turned on their video or is connected to the room for a video call, refer to the isVideoEnabled and the state properties of a Participant object.

It is recommended to show an image such as the user’s profile image as the default image when the didRemoteParticipantEnter(_:) delegate method is invoked.

When the didRemoteParticipantStreamStart(_:) delegate method is invoked, create a new UIImageView and set it to the participant by adding it as a subview on the UITableView or UICollectionView cell.


Reconnect to media stream

Copy link

When a participant loses media stream in a room due to connection issues, Sendbird Calls SDK automatically tries to reconnect the participant’s media streaming in the room. If the Calls SDK fails to reconnect for about 40 seconds, an error will be returned.

class MyClass: RoomDelegate {
    // Called when an error has occurred.
    func didReceiveError(_ error: SBCError, participant: Participant?) {
        // Clear resources for group calls.
    }
}

Note: See the Error codes page for more information.


Cloud recording

Copy link

Cloud recording is a feature that allows you to record participants' audio and video in rooms and download the recorded files from Sendbird Dashboard. When the feature is turned on in a Sendbird application, audio of largeRoomForAudioOnly and audio and video of smallRoomForVideo are recorded.

Activate cloud recording

Copy link

To use the cloud recording feature, contact our support team. You can go to Settings > Calls > General on the dashboard to see if the feature is available for your Sendbird application.

Recording starts in Open rooms when there are more than two participants in the room, and ends when there are no participants. Recorded files will be numbered in the file name and listed in the order of creation.

Download the recorded file

Copy link

Once the file has been uploaded successfully, you can download it from the dashboard. To download the file, click the room of the recording you would like to download on Group calls. You can download the file immediately or later by using the link, which stays valid for 24 hours and can be reissued.

File spec and retention

Copy link

Audio recordings from largeRoomForAudioOnly are processed to .aac files and audio and video recordings from smallRoomForVideo are processed to .mp4 files in default resolution of 1280 x 720. Each file can be downloaded for two weeks from the date the recorded file's upload has completed.