# Sessions A **session** is the most fundamental building block of the Video SDK. A session is similar, but not limited to a virtual meeting where two or more users can communicate with each other over video and audio. Optionally, you can also include features such as [in-session chat](/docs/video-sdk/macos/chat/) and [screen sharing](/docs/video-sdk/macos/share) in a session. ## Create and join a session To create a session, you must provide a session name to uniquely identify it. The process of creating and joining a session requires the developer's [JWT](/docs/video-sdk/auth/#3-pass-the-video-sdk-jwt-to-the-join-function). When you create and join a session through the Video SDK, you must provide a string value representing the session name. The name determines whether the SDK joins an existing session or creates a new one. - If you call `joinSession()` with a session name and there is no session currently active with that name, the SDK creates the session for you. - If a session with that name is currently active, the SDK lets you join the active session if you provide all the required parameters, for example, a password if one has been set for the session. Sessions become inactive and available for reuse after you call `leaveSession()` to end a session or the backend closes the session when there are no longer any users in that session. The session name only needs to be unique to your app at the developer account level. For instance, developers with separate developer accounts (separate SDK credentials) can use the same session name for their separate apps (for example, App A and App B). While the names are the same, Zoom creates different unique sessions for both of these apps. Two different apps built with the Video SDK cannot join sessions created by the other. Each app can only join a session that it created. To create a session through the SDK, create an instance of `ZMVideoSDKSessionContext` and provide the `userName`, `sessionName`, and **SDK JWT** as shown below. ## Create a `SessionContext` object ```swift let sessionContext = ZMVideoSDKSessionContext() // Ensure that you do not hard code JWT or any other confidential credentials in your production app. sessionContext.token = "Your jwt" sessionContext.sessionName = "Your session name" sessionContext.userName = "Your name" sessionContext.sessionPassword = "Your session password" if let session = ZMVideoSDK.shared()?.joinSession(sessionContext) { // Session joined successfully. } ``` ```objectivec ZMVideoSDKSessionContext *sessionContext = [[ZMVideoSDKSessionContext alloc] init]; // Ensure that you do not hard code JWT or any other confidential credentials in your production app. sessionContext.token = @"Your jwt"; sessionContext.sessionName = @"Your session name"; sessionContext.userName = @"Your name"; sessionContext.sessionPassword = @"Your session password"; ZMVideoSDKSession *session = [[ZMVideoSDK sharedZMVideoSDK] joinSession:sessionContext]; if (session) { // Session joined successfully. } ``` The following table describes all the properties of the `sessionContext` object: | Name | Required | Note | | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sessionName` | Yes | Name and unique identifier of the session. A user will be able to join the session by entering the session name. Should be alphanumeric with a max-length of 150 characters. It can include symbols and the space character. Session names are case insensitive (they are all converted to lowercase). This must match the `tpc` value in the [SDK JWT payload](/docs/video-sdk/auth/#payload). | | `userName` | Yes | Display name of the user shown in the session. If empty, the name is displayed as the string "null". Max 200 characters. Values longer than 200 characters are truncated without error. | | `token` | Yes | JWT token generated from your SDK credentials. See [Authorize](/docs/sdk/video/auth/) for details. | | `sessionPassword` | No | Password for session. If set, the session will be private and can only be joined if the user provides a valid password. If not set, the session will be public for anyone in your account. To join, they must use `sessionName` only. The field has a max-length limit of 10 characters, printable ASCII characters only (ch >= 32 && ch < 127). | | `audioOption` | No | Configure audio settings by storing values in `ZMVideoSDKAudioOptions`. | | `videoOption` | No | Configure video settings by storing values in `ZMVideoSDKVideoOptions`. | Prior to joining a session, ensure that you have set up a delegate for callback events by conforming your class to the `ZMVideoSDKDelegate` protocol and using `ZMVideoSDK.shared()?addListener(self)` or `[[ZMVideoSDK sharedZMVideoSDK] addListener:self];`. To successfully monitor events related to a session, you will need to use some important callback functions. Once you have your context and delegate set up, call the `joinSession()` method to join a session. ```swift if let session = ZMVideoSDK.shared()?.joinSession(sessionContext) { // Session joined successfully. } ``` ```objectivec ZMVideoSDKSession *session = [[ZMVideoSDK sharedZMVideoSDK] joinSession:sessionContext]; if (session) { // Session joined successfully. } ``` Note that the return value of the `joinSession()` method will return the session you are attempting to join. To retrieve further information about the joinSession attempt, you must listen for specific callbacks, some of which may require user interaction. ## Leave a session When you are ready to leave the session, you must call the `leaveSession()` method and indicate whether or not you would like to end the session for everyone if you are the host. ```swift // A value of true will end the session, if you are the host. ZMVideoSDK.shared()?.leaveSession(shouldEndSession) ``` ```objectivec // A value of true will end the session, if you are the host. [[ZMVideoSDK sharedZMVideoSDK] leaveSession:shouldEndSession]; ``` ## Manage user information Each user joining a session is assigned an `ZMVideoSDKUser` object to provide access to various user information. This section gives you an overview of user information that you can view and manage. While in a session, you can retrieve the following information of a user: - User ID - Display name (UserName) - Video status - Audio status - Share status - Video Statistic Information - Share Statistic Information - Host status - Manager status - Video pipe - Share pipe - Custom Identity (set on JWT payload) ### Retrieve user To obtain the `ZMVideoSDKUser` associated with the current user, use the `getMySelf` method. ```swift // Get local user. ZMVideoSDK.shared()?.getSessionInfo()?.getMySelf() ``` ```objectivec // Get local user. [[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getMySelf]; ``` To obtain all of the users in the session, use the `getRemoteUsers` method. ```swift // Get all users. ZMVideoSDK.shared()?.getSessionInfo()?.getRemoteUsers() ``` ```objectivec // Get all users in a session. [[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getRemoteUsers]; ``` ### Retrieve user's video A user is tied to an `ZMVideoSDKRawDataPipe` to receive that user's video stream data within a session. To obtain the video pipe of user, use `getVideoPipe` within `ZMVideoSDKUser`. For more information on how to use the pipe, see [Video](/docs/video-sdk/macos/video/). ## User roles and actions People in a session can hold one of the following roles: host, manager, or participant. ### Host The user with the host [`role_type`](/docs/video-sdk/auth/#payload) is the host of the session. A **host** of the session has the following **privileges**. - View information of users in the session. - Change the display name of a user in the session. - Mute or unmute a user's audio. - Transfer the host role to someone else in the session. - Promote another user to be a manager of the session. - Remove participants from the session. - Revoke manager privilege from a user. - Start a live stream. - Prevent other users from sharing their screen (lock screen). - End the session. ### Manager The manager or co-host role can be assigned to a participant by the host to help the host to manage the session participants. A **manager** of the session is assigned the following subset of the **host privileges**. - Remove participants from a session. - Change the display name of a user in the session. - Mute or unmute a user's audio. - Prevent other users from sharing their screen (lock screen). ### Participant A regular user who joins the session without host or manager permission. A participant has **privileges** to view their own information as well as the information of other users. ## Manage users See below for details on how to manage users. ### Change display name If you are the host, you can change your **display name** while in the session using the `changeName` method within `ZMVideoSDKUserHelper`. If you are the host or a manager, you may also change the display name of other users: ```swift ZMVideoSDK.shared()?.getUserHelper().changeName(newName, user: user) ``` ```objectivec [[[ZMVideoSDK sharedZMVideoSDK] getUserHelper] changeName:newName user:user]; ``` ### Transfer host privilege The host of a session can transfer the host role to another user by calling the `makeHost` function within `ZMVideoSDKUserHelper`. ```swift if let localUser = ZMVideoSDK.shared()?.getSessionInfo()?.getMySelf(), localUser.isHost() { // Transfer host privileges to user. ZMVideoSDK.shared()?.getUserHelper().makeHost(user) } ``` ```objectivec // Check if the current user is the host. BOOL localUserIsHost = [[[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getMySelf] isHost]; if (localUserIsHost) { // Transfer host privileges to user. [[[ZMVideoSDK sharedZMVideoSDK] getUserHelper] makeHost:user]; } ``` ### Assign manager role Managers can help manage users while in a session. The host can promote a user to be a manager by calling the `makeManager` method within `ZMVideoSDKUserHelper`. ```swift // Check if the current User is the host. if let localUser = ZMVideoSDK.shared()?.getSessionInfo()?.getMySelf(), localUser.isHost() { // Make User a manager. ZMVideoSDK.shared()?.getUserHelper().makeManager(user) } ``` ```objectivec // Check if the current User is the host. BOOL localUserIsHost = [[[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getMySelf] isHost]; if (localUserIsHost) { // Make User a manager. [[[ZMVideoSDK sharedZMVideoSDK] getUserHelper] makeManager:user]; } ``` ### Revoke manager role The host can revoke the manager role from a user by calling the `revokeManager` method within `ZMVideoSDKUserHelper`. ```swift // Check if the current user is the host. if let localUser = ZMVideoSDK.shared()?.getSessionInfo()?.getMySelf(), localUser.isHost() { // Revoke manager privileges from user. ZMVideoSDK.shared()?.getUserHelper().revokeManager(user) } ``` ```objectivec BOOL localUserIsHost = [[[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getMySelf] isHost]; if (localUserIsHost) { // Revoke manager privileges from User. [[[ZMVideoSDK sharedZMVideoSDK] getUserHelper] revokeManager:user]; } ``` ### Remove user from a session Users with either host or manager privilege can remove users from a session using the `removeUser` method within `ZMVideoSDKUserHelper`. ```swift // Get current user. if let localUser = ZMVideoSDK.shared()?.getSessionInfo()?.getMySelf() { // Check if the current User is the host or a manager. if localUser.isHost() || localUser.isManager() { // Remove user from session. ZMVideoSDK.shared()?.getUserHelper().remove(user) } } ``` ```objectivec // Get current user. ZMVideoSDKUser *localUser = [[[ZMVideoSDK sharedZMVideoSDK] getSessionInfo] getMySelf]; // Check if the current user is the host. BOOL localUserIsHost = [localUser isHost]; // Check if the current user is a manager. BOOL localUserIsAManager = [localUser isManager]; if (localUserIsHost || localUserIsAManager) { // Remove User from session. [[[ZMVideoSDK sharedZMVideoSDK] getUserHelper] removeUser:user]; } ``` ## Callbacks All of these callbacks can be found within your `ZMVideoSDKDelegate` implementation. - `onSessionJoin()` — This is called when the current user has joined the session. - `onSessionLeave()` — This is called when the current user has left the session. - `onError(_ ErrorType: ZMVideoSDKErrors, detail details: Int)` — This is called when the ZMVideoSDK encounters an error (for example, failure to join a session, network timeouts, etc.). The value `ZMVideoSDKErrors_Success (rawValue: 0)` represents a successful callback without errors. - `onUserJoin(_ userHelper: ZMVideoSDKUserHelper!, userList userArray: [ZMVideoSDKUser]!)` — This is called when any user joins the session. The helper is provided to provide user-related functionality. The `userArray` represents the updated array of user IDs of users who have joined the session. - `onUserLeave(_ userHelper: ZMVideoSDKUserHelper!, userList userArray: [ZMVideoSDKUser]!)` — This is called when any user leaves the session. The helper is provided to provide user-related functionality. The `userArray` represents the updated array of user IDs of users who have left the session. - `onSessionNeedPassword(_ handle: ZMVideoSDKpasswordHandler!)` — This is called when attempting to join a session that requires a password, but no password was provided. A `ZMVideoSDKPasswordHandler` is provided to allow the user to retry joining the session. - `onSessionPasswordWrong(_ handle: ZMVideoSDKPasswordHandler!)` — This is called when attempting to join a session that requires a password, but the provided password was incorrect. A `ZMVideoSDKPasswordHandler` is provided to allow the user to retry the password. See [Integrate](/docs/video-sdk/macos/integrate) for more details on how to add a listener delegate. See the following sections for examples. ### Get notified when the local user successfully joins or leaves a session ```swift func onSessionJoin() { // You have successfully joined the session. } func onSessionLeave() { // You have successfully left the session. } ``` ```objectivec - (void)onSessionJoin { // You have successfully joined the session. } - (void)onSessionLeave { // You have successfully left the session. } ``` ### Get notified when other users successfully join or leave a session ```swift func onUserJoin(_ userHelper: ZMVideoSDKUserHelper!, userList userArray: [ZMVideoSDKUser]!) { // UserArray contains the new users. // Use helper to perform actions on a user. if let userArray = userArray { for user in userArray { print(user) } } } func onUserLeave(_ userHelper: ZMVideoSDKUserHelper!, userList userArray: [ZMVideoSDKUser]!) { // UserArray contains the users that recently left. // Use helper to perform actions on a user. if let userArray = userArray { for user in userArray { print(user) } } } ``` ```objectivec - (void)onUserJoin:(ZMVideoSDKUserHelper*)userHelper userList:(NSArray)userArray { // UserArray contains the new users. // Use helper to perform actions on a user. for (int i = 0; i < userArray.count; i++) { NSLog(@"%@", userArray[i]); } } - (void)onUserLeave:(ZMVideoSDKUserHelper*)userHelper userList:(NSArray)userArray { // UserArray contains the users that recently left. // Use helper to perform actions on a user. for (int i = 0; i < userArray.count; i++) { NSLog(@"%@", userArray[i]); } } ``` ### Get notified when the host of the session is changed ```swift func onUserHostChanged(_ userHelper: ZMVideoSDKUserHelper!, user: ZMVideoSDKUser!) { // User is the new host of the session. // Use helper to perform actions on a user. if let userName = user.getUserName() { print("\(userName): is the new host.") } } ``` ```objectivec - (void)onUserHostChanged:(ZMVideoSDKUserHelper*)userHelper user:(ZMVideoSDKUser*)user { // User is the new host of the session. // Use helper to perform actions on a user. if ([user getUserName]) NSLog(@"%@: is the new host.", user.getUserName); } ``` ### Get notified when a password is required to join a session ```swift func onSessionNeedPassword(_ handle: ZMVideoSDKPasswordHandler!) { // Recommended action: prompt user to enter password again and pass user input into completion if let handler = handle { let userInput = "Password" handler.inputSessionPassword(userInput) } // Alternatively, you may abandon the attempt to join the session if let handler = handle { handler.leaveSessionIgnorePassword() } } ``` ```objectivec - (void)onSessionNeedPassword:(ZMVideoSDKPasswordHandler *)handle { // Recommended action: prompt user to enter password again and pass user input into completion NSString *userInput = @"Password"; if (handle) { [handle inputSessionPassword:userInput]; } // Alternatively, you may abandon the attempt to join the session if (handle) { [handle leaveSessionIgnorePassword]; } } ``` ### Get notified when an incorrect password is entered while joining a session ```swift func onSessionPasswordWrong(_ handle: ZMVideoSDKPasswordHandler!) { // Recommended action: prompt user to enter password again and pass user input into completion if let handler = handle { let userInput = "Password" handler.inputSessionPassword(userInput) } // Alternatively, you may abandon the attempt to join the session if let handler = handle { handler.leaveSessionIgnorePassword() } } ``` ```objectivec - (void)onSessionPasswordWrong:(ZMVideoSDKPasswordHandler *)handle { // Recommended action: prompt user to enter password again and pass user input into completion NSString *userInput = @"Password"; if (handle) { [handle inputSessionPassword:userInput]; } // Alternatively, you may abandon the attempt to join the session if (handle) { [handle leaveSessionIgnorePassword]; } } ``` ### Get notified when a user name has changed ```swift func onUserNameChanged(_ user: ZMVideoSDKUser!) { } ``` ```objectivec - (void)onUserNameChanged:(ZMVideoSDKUser*)user { } ``` ### Get notified when a user manager has changed ```swift func onUserManagerChanged(_ user: ZMVideoSDKUser!) { } ``` ```objectivec - (void)onUserManagerChanged:(ZMVideoSDKUser*)user { } ```