In this quickstart, we will introduce you to Daily's Client SDK for iOS by walking through the creation of a simple video call application. By the end of this walkthrough, you'll have a starting point for writing Daily-powered video apps for iOS with Swift.
This walkthrough will implement the following features:
- Creating and joining a public Daily room
- Asking for required application permissions
- Displaying videos from local and remote room participants
- Managing local microphone and camera input
- Leaving the call
You can find the full codebase of this iOS app on GitHub.
Begin by navigating to Daily's developer dashboard and creating a new Daily room.
Give your room a name and click the "Create room" button. All other options can be left at their defaults.
Make note of your Daily room URL. We'll be using it in the code shortly.
Open Xcode and create a new project. Select the App template for your new project from the iOS tab:
In the project details window, enter your project and organization name. Select "Storyboard" in the "Interface" dropdown and click "Next":
You'll be prompted to pick a directory for your project. Once done, click "Create" to finish the process.
With your new project created, you can add the Daily's iOS SDK as a dependency. When building an application using Xcode and Swift, you can use the Swift Package Manager to help you manage application dependencies.
In the top left corner of your Xcode window, press the File tab and select the "Add Packages..." option.
In the search box at the top right hand corner, paste in the GitHub URL of Daily's iOS SDK repository:
daily-client-ios package will appear:
Select "Branch" from the Dependency Rule dropdown and set the branch to
main. Then, click "Add Package".
Xcode will now verify and load the package, then display a "Choose Package Products" dialog. Ensure "Daily" is selected and click "Add Package" again:
In the project details page (which is shown by default), set the project's minimum deployment version to the version of iOS installed on your phone, which must be at least iOS 13.0.
The application will need to be granted permissions to access the internet, use the device camera, and record and play audio.
Click on the parent Xcode project name in the project navigation sidebar:
Click on the "Build Settings" tab and then the "All" sub-tab:
In the "Filter" input box on the right, type "Camera". Once the "Privacy - Camera Usage Description" row appears, double click on the second column and enter:
"Camera is necessary for transmitting video in a call":
Next, do the same with "Privacy - Microphone Usage Description", setting the description to
"Microphone is necessary for transmitting audio in a call".
To ensure that audio will continue uninterrupted when your app is sent to the background, you also need to add the
BackgroundModes capability. To do so, right-click on the
Info.plist file. Choose "Open As -> Source Code" from the context menu. Then, copy and paste the XML code fragment below into the outermost parts of the file's body (
<dict>...</dict>): add the following key and value to the top-level
To confirm your changes are in the right place, refer to the resulting
Info.plist file on GitHub.
After implementing permission handling, we can define the user interface for our application. The UI will support the following functionality:
- Displaying participants' video
- Presenting call controls for toggling the camera/microphone and leaving the meeting
ViewController.swift and declare the following UI elements within the
Next, we're going to configure the application layout in the
main.storyboard file of the project. For that, you'll need some familiarity with the Xcode Interface Builder. Alternatively, you can copy the storyboard source from our existing demo repository.
If you're not already familiar with the Xcode Interface Builder, we've compiled some relevant resources below:
Adding objects to a storyboard:
Connecting storyboard objects to code:
- Add an
@IBOutletconnection to send a message to a UI object
- Add an
@IBActionconnection to receive messages from a UI object
- Add, remove, and modify
main.storyboard file and configure the required UI elements. These will be:
UIButtonto toggle the camera
UIButtonto toggle the microphone
UIButtonto leave the call
UIStackViewfor the participant stack
Next, use the Xcode Objects Library to set the objects for the
ViewController and configure their layout constraints.
Now, connect the
@IBOutlets you just defined in
ViewController to their elements in the Storyboard:
Once the UI is configured, we're ready to build and run the application for the first time. To do so, click "Product -> Run" in the top application menu.
Once loaded, the application will prompt you to grant the necessary permissions. When permissions are granted, it should display the basic application interface you created:
You won't see any video just yet because we haven't set up the call client or joined a Daily room. We'll do that next.
Now that the basics of the application are in place, we can shift our focus to joining and displaying participant videos.
CallClient is the main interface into your Daily video call. It should be instantiated and retained for at least the duration of the video call session.
ViewController.swift and import Daily:
Next, in the
ViewController class, create a instance of the
CallClient object, a
VideoView for the local participant, and a dictionary of
Finally, create a constant called
roomURLString for your Daily room URL.
CallClient instance created, we can set up our application to handle relevant events that occur during a video call. These events are emitted in response to actions like meeting participants joining, leaving, or being updated. We'll handle these events by adding an extension to have
ViewController adopt the
Add the following declaration in
ViewController.swift, underneath the original
viewDidLoad() method, set the call client's delegate to
To reflect accurate camera and microphone states in the local user's call controls, we'll create a function called
updateControls() in the
ViewController class. This function will update the state of the camera and microphone buttons. We'll also call
this.updateControls() from the
viewDidLoad() override method:
To make sure the controls are updated when input settings actually change, add a handler for the
inputsUpdated event within the
When the local particpant's view loads, we should add their video to the stack view in
viewDidLoad(). Additionally, disable the idle timer to keep the device screen active while the app is running. The final
viewDidLoad() method will now look as follows:
When remote participants join the Daily room, the app needs to display their video tracks. To do this, we'll listen for the
participantJoined event in the
Above, when a remote participant joins the room, a new
VideoView instance is created to display their video. The video view's
track property is set to the participant's video track. The new participant is then added to a dictionary of video views. Finally, UI updates are performed and the view is set to update its layout.
We should also handle update events for call participants, which will inform the app when a participant toggles their camera or microphone. To do so, we'll handle the
Above, using our previously created
videoViews dictionary, we can find the video view of the remote participant being updated and modify it accordingly. If the participant being updated is local, we update their tracks using
Finally, when a participant leaves the meeting we'll handle the
After a participant leaves the room, their
VideoView instance in the video views dictionary is removed.
CallClient instantiated set up to handle relevant Daily events, we're ready to have our app join a Daily room.
Create a new
enterRoom() function within the
ViewController class. Within it, invoke the call client's
join() function, passing in the URL of the Daily room that you created earlier.
Call the new
enterRoom() method from the view controller's
To let the user leave the meeting, connect
@IBAction didTapLeaveRoom(_ sender: Any) to the
leaveRoomButton. Then, invoke the the call client's
Run the application. If you are running the app on actual hardware, you should see yourself as the local participant.
If you are running the application in the simulator, you should see a blank video view. This is because the simulator doesn't have access to your camera.
To test the app with a remote participant, open the room URL in your browser on any device. Once you've joined via the browser, the new participant's video should appear in the app view on your iOS device or simulator.
Now that we have participant video being displayed in the app, we'll move on to implementing call controls.
@IBAction didTapToggleMicrophone(_ sender: Any) to the
microphoneInputButton. Use the call client's
setInputEnabled() instance method to toggle the microphone input:
@IBAction didTapToggleCamera(_ sender: Any) to the
cameraInputButton. Use the call client's
setInputEnabled() instance method to toggle the camera input:
This quickstart walked you through the basics of using the Daily's Client SDK for iOS to build a simple video call app. You should now be familiar with:
- How to create the app with appropriate dependencies and permissions
- How to join a Daily room
- How to display participant video in your Android app
- How to toggle the local participant's microphone and camera
- How to leave the Daily room