Introduction
Integrating screen share in an iOS video call app enhances user experience and collaboration. With this feature, users can seamlessly share their screen during calls, facilitating presentations, demonstrations, and remote assistance. Implementing screen sharing requires integrating APIs for capturing device screens, ensuring smooth transmission of visuals, and maintaining privacy controls.
Benefits of Screen Share in iOS Video Call App:
- Enhanced Collaboration: Screen share enables users to collaborate more effectively by sharing documents, presentations, or designs during video calls, fostering better understanding and teamwork.
- Improved Communication: Visual aids facilitate clearer communication, especially for technical support, education, or remote work scenarios, leading to faster issue resolution and knowledge transfer.
- Increased Productivity: With real-time sharing, teams can discuss projects or review documents without the need for additional tools or meetings, saving time and boosting productivity.
Use Cases of Screen Share in iOS Video Call App:
- Business Meetings: Sales teams can share presentations or product demos with clients, enhancing engagement and closing deals more effectively.
- Remote Work: Colleagues can collaborate on projects by sharing screens to discuss documents, designs, or code, replicating in-person collaboration remotely.
- Technical Support: Customer support agents can visually guide users through troubleshooting steps by sharing screens, and resolving issues efficiently.
This tutorial guides you through integrating this valuable feature into your JavaScript video call application using VideoSDK. We'll cover the steps required to leverage VideoSDK's capabilities and implement visual cues that highlight the active speaker within your app's interface.
Getting Started with VideoSDK
VideoSDK enables the opportunity to integrate video & audio calling into Web, Android, and iOS applications with so many different frameworks. It is the best infrastructure solution that provides programmable SDKs and REST APIs to build scalable video conferencing applications. This guide will get you running with the VideoSDK video & audio calling in minutes.
Create a VideoSDK Account
Go to your VideoSDK dashboard and sign up if you don't have an account. This account gives you access to the required Video SDK token, which acts as an authentication key that allows your application to interact with VideoSDK functionality.
Generate your Auth Token
Visit your VideoSDK dashboard and navigate to the "API Key" section to generate your auth token. This token is crucial in authorizing your application to use VideoSDK features. For a more visual understanding of the account creation and token generation process, consider referring to the provided tutorial.
Prerequisites and Setup
- iOS 11.0+
- Xcode 12.0+
- Swift 5.0+
This App will contain two screens:
Join Screen: This screen allows the user to either create a meeting or join the predefined meeting.
Meeting Screen: This screen basically contains local and remote participant views and some meeting controls such as Enable/Disable the mic & Camera and Leave meeting.
Integrate VideoSDK
To install VideoSDK, you must initialize the pod on the project by running the following command:
pod init
It will create the podfile in your project folder, Open that file and add the dependency for the VideoSDK, like below:
pod 'VideoSDKRTC', :git => 'https://github.com/videosdk-live/videosdk-rtc-ios-sdk.git'
then run the below code to install the pod:
pod install
then declare the permissions in Info.plist :
<key>NSCameraUsageDescription</key>
<string>Camera permission description</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone permission description</string>
Project Structure
iOSQuickStartDemo
├── Models
├── RoomStruct.swift
└── MeetingData.swift
├── ViewControllers
├── StartMeetingViewController.swift
└── MeetingViewController.swift
├── AppDelegate.swift // Default
├── SceneDelegate.swift // Default
└── APIService
└── APIService.swift
├── Main.storyboard // Default
├── LaunchScreen.storyboard // Default
└── Info.plist // Default
BroadcastExtension
├── SampleHandler.swift // Default
├── Atomic.swift
└── SocketConnection.swift
├── DarwinNotification.swift
├── SampleUploader.swift
└── Info.plist // Default
Pods
└── Podfile
Create models
Create swift file for MeetingData
and RoomStruct
class model for setting data in object pattern.
Essential Steps for Building the Video Calling
This guide is designed to walk you through the process of integrating Screen Share with VideoSDK. We'll cover everything from setting up the SDK to incorporating the visual cues into your app's interface, ensuring a smooth and efficient implementation process.
Step 1 : Get started with APIClient
Before jumping to anything else, we have to write an API to generate unique meetingId
. You will require an authentication token; you can generate it either using videosdk-server-api-example or from the Video SDK Dashboard for developers.
Step 2: Implement Join Screen
The Join Screen will work as a medium to either schedule a new meeting or join an existing meeting.
Step 3: Initialize and Join Meeting
Using the provided token
and meetingId
, we will configure and initialise the meeting in viewDidLoad()
.
Then, we'll add @IBOutlet for localParticipantVideoView
and remoteParticipantVideoView
, which can render local and remote participant media, respectively.
Step 4: Implement Controls
After initializing the meeting in the previous step, we will now add @IBOutlet for btnLeave
, btnToggleVideo
and btnToggleMic
which can control the media in the meeting.
Step 5: Implementing MeetingEventListener
MeetingEventListener
In this step, we'll create an extension for the MeetingViewController
that implements the MeetingEventListener, which implements the onMeetingJoined
, onMeetingLeft
, onParticipantJoined
, onParticipantLeft
, onParticipantChanged
, onSpeakerChanged
, etc. methods.
Step 6: Implementing ParticipantEventListener
ParticipantEventListener
In this stage, we'll add an extension for the MeetingViewController
that implements the ParticipantEventListener, which implements the onStreamEnabled
and onStreamDisabled
methods for the audio and video of MediaStreams enabled or disabled.
The function update UI is frequently used to control or modify the user interface (enable/disable camera & mic) following the MediaStream state.
class MeetingViewController: UIViewController {
...
extension MeetingViewController: ParticipantEventListener {
/// Participant has enabled mic, video or screenshare
/// - Parameters:
/// - stream: enabled stream object
/// - participant: participant object
func onStreamEnabled(_ stream: MediaStream, forParticipant participant: Participant) {
updateUI(participant: participant, forStream: stream, enabled: true)
}
/// Participant has disabled mic, video or screenshare
/// - Parameters:
/// - stream: disabled stream object
/// - participant: participant object
func onStreamDisabled(_ stream: MediaStream,
forParticipant participant: Participant) {
updateUI(participant: participant, forStream: stream, enabled: false)
}
}
private extension MeetingViewController {
func updateUI(participant: Participant, forStream stream: MediaStream, enabled: Bool) { // true
switch stream.kind {
case .state(value: .video):
if let videotrack = stream.track as? RTCVideoTrack {
if enabled {
DispatchQueue.main.async {
UIView.animate(withDuration: 0.5){
if(participant.isLocal) {
self.localParticipantViewContainer.isHidden = false
self.localParticipantVideoView.isHidden = false
self.localParticipantVideoView.videoContentMode = .scaleAspectFill self.localParticipantViewContainer.bringSubviewToFront(self.localParticipantVideoView)
videotrack.add(self.localParticipantVideoView)
self.lblLocalParticipantNoMedia.isHidden = true
} else {
self.remoteParticipantViewContainer.isHidden = false
self.remoteParticipantVideoView.isHidden = false
self.remoteParticipantVideoView.videoContentMode = .scaleAspectFill
self.remoteParticipantViewContainer.bringSubviewToFront(self.remoteParticipantVideoView)
videotrack.add(self.remoteParticipantVideoView)
self.lblRemoteParticipantNoMedia.isHidden = true
}
}
}
} else {
UIView.animate(withDuration: 0.5){
if(participant.isLocal){
self.localParticipantViewContainer.isHidden = false
self.localParticipantVideoView.isHidden = true
self.lblLocalParticipantNoMedia.isHidden = false
videotrack.remove(self.localParticipantVideoView)
} else {
self.remoteParticipantViewContainer.isHidden = false
self.remoteParticipantVideoView.isHidden = true
self.lblRemoteParticipantNoMedia.isHidden = false
videotrack.remove(self.remoteParticipantVideoView)
}
}
}
}
case .state(value: .audio):
if participant.isLocal {
localParticipantViewContainer.layer.borderWidth = 4.0
localParticipantViewContainer.layer.borderColor = enabled ? UIColor.clear.cgColor : UIColor.red.cgColor
} else {
remoteParticipantViewContainer.layer.borderWidth = 4.0
remoteParticipantViewContainer.layer.borderColor = enabled ? UIColor.clear.cgColor : UIColor.red.cgColor
}
default:
break
}
}
}
...
Known Issue
Please add the following line in the MeetingViewController.swift
file's viewDidLoad
method If you get your video out of the container.
TIP:
Stuck anywhere? Check out this example code on GitHub
Integrate Screen Share in Video App
Step 1: Open Target
Open your project with XCode, the select File > New > Target in menu bar.
Step 2: Select Target
Select Broadcast Upload Extension and click
Step 3: Configure Broadcast Upload Extension
Enter the extension's name in the Product Name field, choose the team from the dropdown, uncheck the "Include UI extension" field, and click "Finish."
Step 4: Activate Extension scheme
You will be prompted with a popup: Activate "Your-Extension-name" scheme? click on activate.
Now, the "Broadcast" folder will appear in the Xcode left side bar.
Step 5: Add an External file in the created extension.
Open the videosdk-rtc-ios-sdk-example repository, and copy the following files: SampleUploader.swift
, SocketConnection.swift
, DarwinNotificationCenter.swift
, and Atomic.swift
to your extension's folder. Ensure that these files are added to the target.
Step 6: Update SampleHandler.swift
file
SampleHandler.swift
fileOpen SampleHandler.swift, and copy the content of the file. Paste this content into your extension's SampleHandler.swift file.
Step 7: Add Capability to the App
In Xcode, navigate to YourappName > Signing & Capabilities, and click on +Capability to configure the app group.
Choose App Groups from the list.
After that, select or add the generated App Group ID that you have created before.
Step 8: Add Capability in Extension
Go to Your-Extension-Name > Signing & Capabilities and configure the App Group functionality which we had performed in previous steps. (Group ID should be same for both targets).
Step 9: Add App Group ID in the Extension File
Go to the extension's SampleHandler.swift
file and paste your group ID into the appGroupIdentifier
constant.
Step 10: Update App level info.plist file
- Add a new key, RTCScreenSharingExtension in Info.plist with the extension's Bundle Identifier as the value.
- Add a new key RTCAppGroupIdentifier in Info.plist with the extension's App groups Id as the value.
Note: For the extension's Bundle Identifier, go to TARGETS > Your-Extension-Name > Signing & Capabilities.
NOTE:
You can also check out the extension's example code on Github.
Integrate ScreenShare in your App
After successfully creating Broadcast Upload Extension using the above-listed steps, we can start using the enableScreenShare
and disableScreenShare
functions of the Meeting
class.
How to use the ScreenShare functions
Use these functions in your app's Meeting Screen.
@IBAction func ScreenShareButtonTapped(_ sender: Any) {
Task {
self.meeting?.enableScreenShare()
}
}
@IBAction func StopScreenShareButtonTapped(_ sender: Any) {
Task {
self.meeting?.disableScreenShare()
}
}
CAUTION:
The functionenableScreenShare
anddisableScreenShare
are async functions; therefore use above syntax to call the ScreenShare functions.
Calling the enableScreenShare()
will prompt a RPBroadcastPickerView
with the extension that was created using the above steps.
After clicking the Start Broadcast button, you will be able to get the screen share stream in the session.
- When the broadcast is started, it creates a Stream that has
MediaStream.kind = .share
. Using the stream kind, you can prompt a ScreenShare view for remote peers when ScreenShare is started by the local peer. - Similarly, you can use the same kind to dismiss the ScreenShare view on the remote peer when the ScreenShare is stopped.
extension MeetingViewController: ParticipantEventListener {
/// Participant has enabled mic, video or screenshare
/// - Parameters:
/// - stream: enabled stream object
/// - participant: participant object
func onStreamEnabled(_ stream: MediaStream, forParticipant participant: Participant) {
if stream.kind == .share {
// show screen share
showScreenSharingView(true)
screenSharingView.showMediastream(stream)
return
}
// show stream in cell
if let cell = self.cellForParticipant(participant) {
cell.updateView(forStream: stream, enabled: true)
}
if participant.isLocal {
// turn on controls for local participant
self.buttonControlsView.updateButtons(forStream: stream, enabled: true)
}
}
/// Participant has disabled mic, video or screenshare
/// - Parameters:
/// - stream: disabled stream object
/// - participant: participant object
func onStreamDisabled(_ stream: MediaStream, forParticipant participant: Participant) {
if stream.kind == .share {
// remove screen share
showScreenSharingView(false)
screenSharingView.hideMediastream(stream)
return
}
// hide stream in cell
if let cell = self.cellForParticipant(participant) {
cell.updateView(forStream: stream, enabled: false)
}
if participant.isLocal {
// turn off controls for local participant
self.buttonControlsView.updateButtons(forStream: stream, enabled: false)
}
}
}
Conclusion
Integrating screen sharing into your iOS video call app with VideoSDK is a straightforward process that unlocks a powerful new feature for your users. This functionality can streamline communication, boost productivity, and open doors for innovative use cases within your app.
Unlock the power of seamless video communication with VideoSDK! Sign up now and dive into an extraordinary world of interactive video-calling experiences.
With VideoSDK, you get a generous 10,000 free minutes to kickstart your journey towards creating engaging and immersive connections. Whether you're building a social app, a collaboration tool, or an e-learning platform, our platform provides the tools you need to elevate your user experience to the next level.