Quickstart
Updated
Build a basic voice calling, video calling, or streaming app with the Agora RTC SDK.
This page provides a step-by-step guide on how to create a basic real-time app using the Agora RTC SDK. The same steps apply whether you're building voice calling, video calling, interactive live streaming, or broadcast streaming — only a few configuration values change based on your use case.
Understand the tech
To start a real-time session, implement the following steps in your app:
-
Initialize the engine: Before calling other APIs, create and initialize an engine instance.
-
Join a channel: Call methods to create and join a channel.
-
Join as a host: A live streaming event has one or more hosts. A host publishes audio and video to the channel and can also subscribe to streams from other hosts.
-
Join as audience: Audience members can only subscribe to streams published by hosts.
Note
For the voice calling and video calling use cases, each user joins as a host.
-
-
Send and receive audio and video: Hosts publish streams to the channel. Audience members subscribe to audio and video streams published by hosts.
-
For streaming applications, set the latency level based on your use case:
-
Interactive live streaming: Optimized for real-time interaction with ultra-low latency. Use this when hosts and audience need to interact quickly, such as in live Q&A sessions, interactive classrooms, or auctions.
-
Broadcast streaming: Optimized for scalability with slightly higher latency. Use this for large-scale events where one-way broadcasting is sufficient, such as concerts, sports events, or news broadcasts.
-
Prerequisites
- A camera and a microphone.
- A valid Agora account and project. See Agora account management for details.
- Xcode 13.0 or higher.
- An Apple developer account.
- If you use CocoaPods to integrate the SDK, make sure CocoaPods is installed.
- Two devices running macOS 10.10 or higher.
Set up your project
Follow these steps to create a project in Xcode:
-
Refer to Create a project. Under Application, select App. Use Storyboard for the user interface and choose Swift as the programming language.
Note
If you have not added the development team information, you see the Add account... button. Click the button and follow the on-screen prompts to log in to your Apple ID. Once login is complete, click Next, and choose your Apple account as the development team.
-
Set up automatic signing for your project.
-
Set the target devices where your app will be deployed.
-
Create a user interface for your app. Refer to Create a user interface to create a bare-bones UI.
Follow these steps to add Realtime Communication to your Xcode project:
- Open your project in Xcode.
- Set the target devices where your app will be deployed.
- Create a user interface for your app. Refer to Create a user interface to create a bare-bones UI.
Install the SDK
Use one of the following methods to install the RTC SDK.
-
In Xcode, go to File > Add Package Dependencies.
-
In the search bar, paste the following URL:
https://github.com/AgoraIO/AgoraRtcEngine_macOS.git -
Click Add Package, select the latest version, and click Next.
-
For basic Realtime Communication, select RtcBasic.
If needed, also select:
SpatialAudiofor spatial audio effects.VirtualBackgroundfor virtual background.
-
Under Add to Target, select your project and click Add Package.
For more information, see Apple's official documentation.
-
Go to the project root directory in Terminal and run
pod init. A text file namedPodfileis generated in the project folder. -
Open
Podfileand modify the content as follows. ReplaceYour Appwith your target name.platform :macos, '10.11' target 'Your App' do # Replace x.y.z with the specific SDK version number, such as 4.4.0. pod 'AgoraRtcEngine_macOS', 'x.y.z' endGet the latest version number from the release notes.
-
Run
pod installin Terminal to install the RTC SDK. After successful installation, Terminal shows Pod installation complete!. -
After successful installation, a file with the suffix
.xcworkspaceis generated in the project folder. Open the file in Xcode for subsequent operations.
-
Download the latest version of the SDK from SDKs download and extract the contents.
-
Copy the files in the
libsfolder of the SDK package to your project directory. -
Open Xcode and add the corresponding dynamic library. Make sure the Embed property of the added dynamic library is set to Embed & Sign.
Note
Agora SDK uses
libc++(LLVM) by default. If you need to uselibstdc++(GNU), contactsupport@agora.io. The library provided by the SDK is a FAT image that includes simulator and device builds.
Note
The privacy updates for App Store submissions released by Apple require developers to declare approved reasons for using a set of APIs in their app's privacy manifest. Agora provides a PrivacyInfo.xcprivacy file that you can include in your project.
Implement Realtime Communication
This section guides you through the implementation of basic real-time audio and video interaction in your app.
The following figure illustrates the essential steps:
This guide includes complete sample code that demonstrates implementing basic real-time interaction. To understand the core API calls in the sample code, review the following implementation steps.
Import Agora framework
Add the following import to your swift file:
import Cocoa
import AgoraRtcKitInitialize the engine
Call sharedEngine(withAppId:delegate:) to create and initialize an AgoraRtcEngineKit instance. Provide your App ID and an AgoraRtcEngineDelegate implementation to handle SDK events.
var agoraKit: AgoraRtcEngineKit!
let appId = "YOUR_AGORA_APP_ID"
// Initialize the Agora engine
func initializeAgoraVideoSDK() {
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: appId, delegate: self)
}Join a channel
To join a channel, call joinChannel with the following parameters:
-
Channel name: The name of the channel to join. Clients that pass the same channel name join the same channel. If a channel with the specified name does not exist, it is created when the first user joins.
-
Authentication token: A dynamic key that authenticates a user when the client joins a channel. In a production environment, you obtain a token from a token server in your security infrastructure. For the purpose of this guide Generate a temporary token.
-
User ID: A 32-bit signed integer that identifies a user in the channel. You can specify a unique user ID for each user yourself. If you set the user ID to
0when joining a channel, the SDK generates a random number for the user ID and returns the value in thedidJoinChannelcallback. -
Channel media options: Configure
AgoraRtcChannelMediaOptionsto define publishing and subscription settings, optimize performance for your specific use-case, and set optional parameters.
Set the channelProfile, clientRoleType, and audienceLatencyLevel according to your use case:
| Use case | Channel profile | Client role | Latency level |
|---|---|---|---|
| Voice calling | .communication | .broadcaster | N/A |
| Video calling | .communication | .broadcaster | N/A |
| Interactive live streaming | .liveBroadcasting | .broadcaster or .audience | .ultraLow (default) |
| Broadcast streaming | .liveBroadcasting | .broadcaster or .audience | .low |
Note
- Only broadcasters can publish media. Audience members cannot publish until promoted to broadcaster.
- Choose Communication mode for calls where every user publishes, typically fewer than 17 participants. Choose Live Broadcasting mode for larger events with separate hosts and audience.
- The latency level only applies to the audience role, and affects your pricing tier.
The following example shows the configuration for interactive live streaming with the broadcaster role:
let channelName = "demo" // Replace with your actual channel name
let token = "<Authentication token>" // Replace with your token
// Join the channel with specified options
func joinChannel() {
let options = AgoraRtcChannelMediaOptions()
// Set the channel profile according to your use case (see table above)
options.channelProfile = .liveBroadcasting
// Set the user role to .broadcaster (host) or .audience according to your use case
options.clientRoleType = .broadcaster
// Only takes effect when clientRoleType is .audience
options.audienceLatencyLevel = .low
// Publish audio captured by microphone
options.publishMicrophoneTrack = true
// Publish video captured by camera
options.publishCameraTrack = true
// Auto subscribe to all audio streams
options.autoSubscribeAudio = true
// Auto subscribe to all video streams
options.autoSubscribeVideo = true
// Use a temporary Token to join the channel
agoraKit.joinChannel(
byToken: token,
channelId: channelName,
uid: 0,
mediaOptions: options
)
}To change a user's role after joining (for example, promoting an audience member to broadcaster), call setClientRole:
let role: AgoraClientRole = .broadcaster
let options = AgoraClientRoleOptions()
options.audienceLatencyLevel = .low
agoraKit.setClientRole(role, options: options)Subscribe to RTC SDK events
The RTC SDK provides a delegate for handling channel events. To use it, conform to the AgoraRtcEngineDelegate protocol in your class and implement the event methods you want to handle. The following code implements the didJoinChannel, didOfflineOfUid, and didJoinedOfUid callbacks:
Note
To ensure that you receive all RTC SDK events, set the engine event handler before joining a channel.
// Extension for handling Agora SDK callbacks
extension ViewController: AgoraRtcEngineDelegate {
// Triggered when the local user successfully joins a channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
print("Successfully joined channel: \(channel) with UID: \(uid)")
}
// Triggered when a remote user joins the channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
setupRemoteVideo(uid: uid, view: remoteView)
}
// Triggered when a remote user leaves the channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
setupRemoteVideo(uid: uid, view: nil)
}
}To learn about the other SDK events, see AgoraRtcEngineDelegate.
Enable the video module
Follow the steps below to set up the video module.
-
To enable the video module, call
enableVideo. -
To enable local video preview, call
startPreview.// Enable video functionality (audio is enabled by default) agoraKit.enableVideo() // Enable local video preview agoraKit.startPreview()
Display the local video
Call setupLocalVideo to initialize the local view and set the local video display properties.
// Configures and starts displaying the local video feed
func setupLocalVideo() {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.view = localView
videoCanvas.uid = 0 // UID 0 is assigned to the local user
videoCanvas.renderMode = .hidden
agoraKit.setupLocalVideo(videoCanvas)
}Display remote video
To initialize the remote user view, call setupRemoteVideo and set the local display properties for the remote user. Use the didJoinedOfUid callback to get the UID of the remote user.
func setupRemoteVideo(uid: UInt, view: UIView?) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = view // Assign view for joining, set to nil for leaving
videoCanvas.renderMode = .hidden
agoraKit.setupRemoteVideo(videoCanvas)
}Handle permissions
To access the camera and microphone, add the required permissions for real-time interaction. Open the info.plist file from the project navigation bar, edit the property list, to add the required permissions. These permissions are optional. However, if you do not add these permissions, you will not be able to use the corresponding devices.
| Key | Type | Value |
|---|---|---|
| Privacy - Microphone Usage Description | String | For the purpose of using the microphone. For example, for a call or live interactive streaming session. |
| Privacy - Camera Usage Description | String | For the purpose of using the camera. For example, for a call or live interactive streaming session. |
Note
- If your project depends on third-party plugins or libraries, such as a third-party camera library, and the signature of the plug-in or library is inconsistent with the signature of the project, check the Hardened Runtime settings. Specifically, review and potentially disable Runtime Exceptions and Library Validation in the project configuration.
- For further information, refer to Preparing your app for distribution.
Configure your macOS project settings by navigating to TARGETS > Project Name > Signing & Capabilities. Enable App Sandbox and Hardened Runtime, and add the necessary permissions as follows:
| Capability | Category | Permission |
|---|---|---|
| App Sandbox | Network |
|
| App Sandbox | Hardware |
|
| Hardened Runtime | Resource Access |
|
Start and close the app
When the user launches the app, it joins the channel and starts Realtime Communication. When the user closes the app, it leaves the channel and ends Realtime Communication.
-
To start Video Calling, call the following methods:
// Initialize the Agora engine initializeAgoraVideoSDK() // Start the local video preview setupLocalVideo() // Join an Agora channel joinChannel() -
To leave the channel and release SDK resources when the app is closed, call the following methods:
// Stop local video preview agoraKit.stopPreview() // Leave the channel and release session-related resources agoraKit.leaveChannel(nil) // Release all resources used by the Agora SDK AgoraRtcEngineKit.destroy()
caution
After destroying the engine, you can no longer use SDK methods and callbacks. To use the real-time interaction functions again, create a new engine. See Initialize the engine for details.
Complete sample code
A complete code sample demonstrating the basic process of real-time interaction is provided for your reference. Copy the following code into your ViewController.swift file:
Create a user interface
To connect the sample code to your existing UI, ensure that your ViewController.swift file includes the UIViews used to Display the local video and Display remote video.
Alternatively, use the following sample code to generate a basic user interface. To use this interface, replace the contents of the ViewController.swift file with the following code:
Sample code to create the user interface
import Cocoa
import AgoraRtcKit
// ViewController.swift
class ViewController: NSViewController {
// UI view for displaying the local video stream
var localView: NSView!
// UI view for displaying the remote video stream
var remoteView: NSView!
override func viewDidLoad() {
super.viewDidLoad()
// Set up the user interface
setupUI()
}
func setupUI() {
guard let screenFrame = NSScreen.main?.frame else { return } // Ensure screen is available
// Create the local video view covering the full screen
localView = NSView(frame: screenFrame)
// Create the remote video view positioned in the top-right corner
remoteView = NSView(frame: CGRect(x: self.view.bounds.width - 135, y: 50, width: 250, height: 250))
// Add video views to the main view
self.view.addSubview(localView)
self.view.addSubview(remoteView)
}
}Test the sample code
Take the following steps to test the sample code:
-
In your code update the
appIdandtoken, with the app ID and temporary token you obtained from Agora Console. Use the samechannelNameyou filled in when generating the temporary token. -
Click Build to run your project and wait a few seconds for the app installation to complete.
-
Allow the app to access the device's microphone and camera.
-
On a second device, repeat the previous steps to install and launch the client. Alternatively, use the Web demo to join the same channel and test the following use-cases:
- If users on both devices join the channel as hosts, they can see and hear each other.
- If one user joins as host and the other as audience, the host can see themselves in the local video window; the audience can see the host in the remote video window and hear the host.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects of this product.
- If a firewall is deployed in your network environment, refer to Connect with Cloud Proxy to use Agora services normally.
Next steps
After implementing the quickstart sample, read the following documents to learn more:
- To ensure communication security in a test or production environment, best practice is to obtain and use a token from an authentication server. For details, see Secure authentication with tokens.
Sample project
Agora provides open source sample projects on GitHub for your reference. Download or view the JoinChannelVideo project for a more detailed example.
API reference
Frequently asked questions
- How can I fix black screen issues?
- Why can't I turn on the camera?
- How can I listen for audience joining or leaving a channel?
- How can I solve channel-related issues?
- How can I set the log file?
- How can I troubleshoot the issue of no sound?
