# Whiteboard sharing The Video SDK lets an app share a whiteboard within a session, allowing users to start, view, and collaborate on a digital canvas. Manage this feature through the dedicated `ZMVideoSDKWhiteboardHelper`. ## Integrate the module To add whiteboard support to your app, you will primarily use the `ZMVideoSDKWhiteboardHelper` interface, which is part of the `ZMVideoSDKShareHelper` interface. You can also manage events using the `ZMVideoSDKDelegate` protocol. ## Share and manage the whiteboard These helper classes are available for you to manage the whiteboard. | **Method** | **Purpose** | | --------------------------- | ------------------------------------------------------------------ | | `getWhiteboardHelper()` | Retrieves the instance of the whiteboard helper. | | `canStartShareWhiteboard()` | Checks if the current user is permitted to start a new whiteboard. | | `startShareWhiteboard()` | Starts a new, blank whiteboard session. | | `canStopShareWhiteboard()` | Checks if the current user can stop the active whiteboard share. | | `stopShareWhiteboard()` | Stops the current whiteboard share. | ```swift // 1. Get the Whiteboard Helper if let whiteboardHelper = ZMVideoSDK.shared().getShareHelper().getWhiteboardHelper() { // 2. Start Sharing if whiteboardHelper.canStartShareWhiteboard() { let result = whiteboardHelper.startShareWhiteboard() // Check 'result' for success (.success) } // 3. Stop Sharing if whiteboardHelper.canStopShareWhiteboard() { let result = whiteboardHelper.stopShareWhiteboard() // Check 'result' for success } } ``` ```cpp // 1. Get the Whiteboard Helper ZMVideoSDKWhiteboardHelper *whiteboardHelper = [[[ZMVideoSDK sharedVideoSDK] getShareHelper] getWhiteboardHelper]; // 2. Start Sharing if ([whiteboardHelper canStartShareWhiteboard]) { ZMVideoSDKErrors result = [whiteboardHelper startShareWhiteboard]; // Check 'result' for success (ZMVideoSDKErrors_Success) } // 3. Stop Sharing if ([whiteboardHelper canStopShareWhiteboard]) { ZMVideoSDKErrors result = [whiteboardHelper stopShareWhiteboard]; // Check 'result' for success } ``` ## View or subscribe to the whiteboard Use the SDK interfaces `subscribeWhiteboard`, `unSubscribeWhiteboard`, `setWhiteboardViewPos`, and `setWhiteboardViewSize` to control the display of the whiteboard in a dedicated window or view. You manage the position and size using `NSPoint` and `NSSize`. | **Method** | **Purpose** | |----------------------------|-----------------------------------------------------------------------| | `subscribeWhiteboard` | Displays the whiteboard view when someone is sharing the whiteboard. | | `unSubscribeWhiteboard` | Closes the whiteboard view. | | `setWhiteboardViewPos` | Sets the top-left position (NSPoint) of the whiteboard view. | | `setWhiteboardViewSize` | Sets the size (NSSize) of the whiteboard view. | | `isOtherSharingWhiteboard` | Checks if any other user is currently sharing a whiteboard. | ### To view the whiteboard ```swift // Get the helper as shown above if let whiteboardHelper = ZMVideoSDK.shared().getShareHelper().getWhiteboardHelper() { // 1. Subscribe to the whiteboard on your selected NSWindow whiteboardHelper.subscribeWhiteboard(selectedNSWindow) // 2. Set the position and size of the whiteboard window/view let position = NSPoint(x: 100, y: 100) // e.g. x=100, y=100 let size = NSSize(width: 800, height: 600) // e.g. width=800, height=600 whiteboardHelper.setWhiteboardViewPos(position) whiteboardHelper.setWhiteboardViewSize(size) } ``` ```cpp // Get the helper as shown above ZMVideoSDKWhiteboardHelper *whiteboardHelper = [[[ZMVideoSDK sharedVideoSDK] getShareHelper] getWhiteboardHelper]; // 1. Subscribe to the whiteboard on your selected NSWindow [whiteboardHelper subscribeWhiteboard:selectedNSWindow]; // 2. Set the position and size of the whiteboard window/view NSPoint position = NSMakePoint(100, 100); // e.g. x=100, y=100 NSSize size = NSMakeSize(800, 600); // e.g. width=800, height=600 [whiteboardHelper setWhiteboardViewPos:position]; [whiteboardHelper setWhiteboardViewSize:size]; ``` ### To stop viewing the whiteboard ```swift // Get the helper as shown above if let whiteboardHelper = ZMVideoSDK.shared().getShareHelper().getWhiteboardHelper() { whiteboardHelper .unSubscribeWhiteboard() } ``` ```cpp // Get the helper as shown above ZMVideoSDKWhiteboardHelper *whiteboardHelper = [[[ZMVideoSDK sharedVideoSDK] getShareHelper] getWhiteboardHelper]; [whiteboardHelper unSubscribeWhiteboard]; ``` ## Whiteboard events and status changes You'll handle whiteboard events in your `ZMVideoSDKDelegate` implementation. | **CallbackMethod** | **Purpose** | |-----------------------|--------------------| | `(void)onUserWhiteboardShareStatusChanged:(ZMVideoSDKUser *)user whiteboardHelper:(ZMVideoSDKWhiteboardHelper *)whiteboardHelper {}` | Called when any user starts or stops sharing a whiteboard. This is your cue to subscribe or unsubscribe. | | `ZMVideoSDKUser.getWhiteboardStatus()` | Returns a user's current whiteboard status (.started or .stopped). | ```swift // Implement this method in your class that conforms to ZMVideoSDKDelegate func onUserWhiteboardShareStatusChanged(_ user: ZMVideoSDKUser, whiteboardHelper: ZMVideoSDKWhiteboardHelper) { if user.getWhiteboardStatus() == ZMVideoSDKWhiteboardStatus_Started { // A user has started sharing a whiteboard. Subscribe to the whiteboard on your selected NSWindow whiteboardHelper.subscribeWhiteboard(selectedNSWindow) // 2. Set the position and size of the whiteboard window/view let position = NSPoint(x: 100, y: 100) let size = NSSize(width: 800, height: 600) whiteboardHelper.setWhiteboardViewPos(position) whiteboardHelper.setWhiteboardViewSize(size) } else { // The whiteboard sharing has ended. Unsubscribe to close the view. whiteboardHelper.unSubscribeWhiteboard() } } ``` ```cpp // Implement this method in your class that conforms to ZMVideoSDKDelegate - (void)onUserWhiteboardShareStatusChanged:(ZMVideoSDKUser *)user whiteboardHelper:(ZMVideoSDKWhiteboardHelper *)whiteboardHelper { if ([user getWhiteboardStatus] == ZMVideoSDKWhiteboardStatus_Started) { // A user has started sharing a whiteboard. Subscribe to the whiteboard on your selected NSWindow [whiteboardHelper subscribeWhiteboard:selectedNSWindow]; // Example: Set initial position and size NSPoint position = NSMakePoint(100, 100); NSSize size = NSMakeSize(800, 600); [whiteboardHelper setWhiteboardViewPos:position]; [whiteboardHelper setWhiteboardViewSize:size]; } else { // The whiteboard sharing has ended. Unsubscribe to close the view. [whiteboardHelper unSubscribeWhiteboard]; } } ``` ## Export whiteboard content Export the whiteboard as a PDF document. | **Method/Enum** | **Purpose** | |-------------------------|-----------------| | `(ZMVideoSDKErrors)exportWhiteboard:(ZMVideoSDKExportFormat)format` | Triggers the asynchronous export process. Currently supports .PDF. | | `ZMVideoSDKExportFormat` | The enum value to specify PDF as the export format. | | `(void)onWhiteboardExported:(ZMVideoSDKExportFormat)format data:(unsigned char *)data dataLength:(long)length {}` | The delegate callback that provides the exported file data as an `unsigned char *`(Objective-C) or `UnsafeMutablePointer` (Swift) object. | ### To export and retrieve the data ```swift // 1. Trigger the export if let whiteboardHelper = ZMVideoSDK.shared().getShareHelper().getWhiteboardHelper() { whiteboardHelper.exportWhiteboard(ZMVideoSDKExportFormat_PDF) } // 2. Receive the data in your delegate func onWhiteboardExported(_ format: ZMVideoSDKExportFormat, data: UnsafeMutablePointer, dataLength length: Int) { if format == ZMVideoSDKExportFormat_PDF { // 'data' is the Swift UnsafeMutablePointer object of the PDF file. // You can now write these data to a file on the device. savePdfFile(data) } } ``` ```cpp // 1. Trigger the export ZMVideoSDKWhiteboardHelper *whiteboardHelper = [[[ZMVideoSDK sharedVideoSDK] getShareHelper] getWhiteboardHelper]; [whiteboardHelper exportWhiteboard:ZMVideoSDKExportFormat_PDF]; // 2. Receive the data in your delegate - (void)onWhiteboardExported:(ZMVideoSDKExportFormat)format data:(unsigned char *)data dataLength:(long)length { if (format == ZMVideoSDKExportFormat_PDF) { // 'data' is the (unsigned char *) object of the PDF file. // You can now write these data to a file on the device. [self savePdfFile:data]; } } ``` ## Manage the data Because the whiteboard data isn't stored in the cloud, you'll need to handle the data storage. Data can be lost when someone stops sharing the whiteboard, a user leaves a session, or when a user joins a sub-session, or when the app crashes or has network connectivity issues.