Use this guide to quickly start an interactive broadcast demo with the Agora Video SDK for macOS.

The difference between a broadcast and a call is that users have roles in a broadcast. You can set your role as either Broadcaster or Audience. The broadcaster sends and receives streams while the audience receives streams only.

Try the demo

We provide an open-source OpenLive-macOS-Objective-C/OpenLive-macOS-Swift demo project that implements the basic video broadcast on GitHub. You can try the demo and view the source code.


  • Xcode 9.0 or later
  • A macOS device running macOS 10.10 or later
  • A valid Agora account. (Sign up for free)
Open the specified ports in Firewall Requirements if your network has a firewall.

Set up the development environment

In this section, we will create a macOS project, and integrate the SDK into the project.

Create a macOS project

Now, let's build a macOS project from scratch. Skip to Integrate the SDK if a macOS project already exists.

Create a macOS project
  1. Open Xcode and click Create a new Xcode project.

  2. Choose Cocoa App as the template and click Next.

  3. Input the project information, such as the project name, team, organization name, and language, and click Next.

    If you haven't added any team information, you will see an Add account... button. Click it, input your Apple ID, and click Next to add your team.
  4. Choose the storage path of the project and click Create.

  5. Go to the TARGETS > Project Name > General > Signing menu, choose Automatically manage signing, and then click Enable Automatic on the pop-up window.

Integrate the SDK

Choose either of the following methods to integrate the Agora SDK into your project.

Method 1: Automatically integrate the SDK with CocoaPods

  1. Ensure that you have installed CocoaPods before the following steps. See the installation guide in Getting Started with CocoaPods.
  2. In Terminal, go to the project path and run the pod init command to create a Podfile in the project folder.
  3. Open the Podfile, delete all contents and input the following contents. Remember to change Your App to the target name of your project.
    # platform :macOS, '10.11' use_frameworks!
    target 'Your App' do
      pod 'AgoraRtcEngine_macOS'
  4. Go back to Terminal, and run the pod update command to update the local libraries.
  5. Run the pod install command to install the Agora SDK. Once you successfully install the SDK, it shows Pod installation complete! in Terminal, and you can see an xcworkspace file in the project folder.
  6. Open the generated xcworkspace file in Xcode.

Method 2: Manually add the SDK files

  1. Go to SDK Downloads, download the latest version of the Agora SDK for macOS, and unzip the downloaded SDK package.

  2. Copy the AgoraRtcEngineKit.framework file in the libs folder to the project folder.

  3. In Xcode, go to the TARGETS > Project Name > Build Phases > Link Binary with Libraries menu, and click + to add the following frameworks and libraries. To add the AgoraRtcEngineKit.framework file, remember to click Add Other... after clicking +.

    • AgoraRtcEngineKit.framework
    • Accelerate.framework
    • CoreWLAN.framework
    • libc++.dylib
    • libresolv.9.tbd
    • SystemConfiguration.framework
    • VideoToolbox.framework



Add project permissions

  1. Add the following permissions in the info.plist file for device access according to your needs:
Key Type Value
Privacy - Microphone Usage Description String To access the microphone, such as for a video call.
Privacy - Camera Usage Description String To access the camera, such as for a video call.



  1. If you enable the App Sandbox or Hardened Runtime settings in your project, check the following items to add the corresponding permissions:
Menu Category Item
App Sandbox Network Incoming Connections (Server)
Incoming Connections (Client)
Hardware Camera
Audio Input
Hardened Runtime Resource Access Camera
Audio Input
According to the requirements of Apple:
  • Mac software distributed in the Mac App Store must enable the App Sandbox setting. See details in Apple News and Updates.
  • Mac software distributed outside the Mac App Store must enable the Hardened Runtime setting. See details in Apple News and Updates.

Implement the basic broadcast

This section introduces how to use the Agora SDK to make an interactive broadcast. The following figure shows the API call sequence of a basic video broadcast.

1. Create the UI

Create the user interface (UI) for the interactive broadcast your project. Skip to Import the class if you already have a UI in your project.

If you are implementing a video broadcast, we recommend adding the following elements into the UI:

  • The view of the broadcaster
  • The exit button

When you use the UI setting of the demo project, you can see the following interface:

2. Import the class

Import the AgoraRtcEngineKit class in your project.

// Objective-C
#import <AgoraRtcEngineKit/AgoraRtcEngineKit.h>
// Swift
import AgoraRtcEngineKit
The Agora Native SDK uses libc++ (LLVM) by default. Contact Agora support If you want to use libstdc++ (GNU). The SDK provides FAT image libraries with multi-architecture support for both 32/64-bit audio emulators and 32/64-bit audio/video real devices.

3. Initialize AgoraRtcEngineKit

Create and initialize the AgoraRtcEngineKit object before calling any other Agora APIs.

In this step, you need to use the App ID of your project. Follow these steps to create an Agora project in Console and get an App ID.

  1. Go to Console and click the Project Management icon on the left navigation panel.
  2. Click Create and follow the on-screen instructions to set the project name, choose an authentication mechanism, and Click Submit.
  3. On the Project Management page, find the App ID of your project.

Call the sharedEngineWithAppId method and pass in the App ID to initialize the AgoraRtcEngineKit object.

You can also listen for callback events, such as when the local user joins the channel, and when the first video frame of a remote user is decoded.

// Objective-C
- (void)initializeAgoraEngine {
    // Input your App ID to initialize the AgoraRtcEngineKit object.
    self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:appID delegate:self];
// Swift
func initializeAgoraEngine() {
   // Initialize the AgoraRtcEngineKit object.
   agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: AppID, delegate: self)

4. Set the channel profile

After initializing the AgoraRtcEngineKit object, call the setChannelProfile method to set the channel profile as Live Broadcast.

One AgoraRtcEngineKit object uses one profile only. If you want to switch to another profile, destroy the current AgoraRtcEngineKit object with the destroy method and create a new one before calling the setChannelProfile method.

// Objective-C
// Set the channel profile.
[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
// Swift
// Set the channel profile.

5. Set the client role

A Live Broadcast channel has two client roles: Broadcaster and Audience, and the default role is Audience. After setting the channel profile to Live Broadcast, your app may use the following steps to set the client role:

  1. Allow the user to set the role as Broadcaster or Audience.
  2. Call the setClientRole method and pass in the client role set by the user.

Note that in a live broadcast, only the broadcaster can be heard and seen. If you want to switch the client role after joining the channel, call the setClientRole method.

// Objective-C
 if (self.isBroadcaster) {
        self.clientRole = AgoraClientRoleAudience;
        if (self.fullSession.uid == 0) {
            self.fullSession = nil;
    } else {
        self.clientRole = AgoraClientRoleBroadcaster;
    // Set the client role.
    [self.rtcEngine setClientRole:self.clientRole];
// Swift
// Set the client role.

6. Set the local video view

If you are implementing an audio broadcast, skip to Join a channel.

After setting the channel profile and client role, set the local video view before joining the channel so that the broadcaster can see the local video in the broadcast. Follow these steps to configure the local video view:

  1. Call the enableVideo method to enable the video module.
  2. Call the setupLocalVideo method to configure the local video display settings.
// Objective-C
// Enable the video module.
[self.agoraKit enableVideo];
- (void)setupLocalVideo {
    AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
    videoCanvas.uid = 0;
    videoCanvas.view = self.localVideo;
    videoCanvas.renderMode = AgoraVideoRenderModeHidden;
    // Setup the local video view.
    [self.agoraKit setupLocalVideo:videoCanvas];
// Swift
// Enable the video module.
func addLocalSession() {
    let localSession = VideoSession.localSession()
    // Setup the local video view.
    let mediaInfo = MediaInfo(dimension: settings.dimension,
                                  fps: settings.frameRate.rawValue)
    localSession.mediaInfo = mediaInfo

7. Join a channel

After initializing the AgoraRtcEngineKit object and setting the local video view (for a video call), you can call the joinChannelByToken method to join a channel. In this method, set the following parameters:

  • channelId: Specify the channel name that you want to join. Input your channelId before running the sample code.

  • token: Pass a token that identifies the role and privilege of the user. You can set it as one of the following values:

    • nil.
    • A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see Get a Temporary Token.
    • A token generated at the server. This applies to scenarios with high-security requirements. For details, see Generate a token from Your Server.
    If your project has enabled the app certificate, ensure that you provide a token.
  • uid: ID of the local user that is an integer and should be unique. If you set uid as 0, the SDK assigns a user ID for the local user and returns it in the joinSuccessBlock callback.

  • joinSuccessBlock: Returns that the user joins the specified channel. It is same as didJoinChannel. We recommend setting joinSuccessBlock as nil, so that the SDK can trigger the didJoinChannel callback.

For more details on the parameter settings, see joinChannelByToken.

// Objective-C
- (void)joinChannel {
    // Join a channel with a token.
    [self.agoraKit joinChannelByToken:token channelId:@"demoChannel1" info:nil uid:0 joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) {
// Swift
// Join a channel with a token.
agoraKit.joinChannel(byToken: KeyCenter.Token, channelId: channelId, info: nil, uid: 0, joinSuccess: nil)

8. Set the remote video view

In a video call, you should be able to see other users too. This is achieved by calling the setupRemoteVideo method after joining the channel.

Shortly after a remote user joins the channel, the SDK gets the remote user's ID in the firstRemoteVideoDecodedOfUid callback. Call the setupRemoteVideo method in the callback, and pass in the uid to set the video view of the remote user.

// Objective-C
// Listen for the firstRemoteVideoDecodedOfUid callback.
// This callback occurs when the first video frame of a remote user is received and decoded after the remote user successfully joins the channel.
// You can call the setupRemoteVideo method in this callback to set up the remote video view.
- (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size: (CGSize)size elapsed:(NSInteger)elapsed {
    if (self.remoteVideo.hidden) {
        self.remoteVideo.hidden = NO;
    AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
    videoCanvas.uid = uid;
    videoCanvas.view = self.remoteVideo;
    videoCanvas.renderMode = AgoraVideoRenderModeHidden;
    // Set the remote video view.
    [self.agoraKit setupRemoteVideo:videoCanvas];
// Swift
// Listen for the firstRemoteVideoDecodedOfUid callback.
// This callback occurs when the first video frame of a remote user is received and decoded after the remote user successfully joins the channel.
// You can call the setupRemoteVideo method in this callback to set up the remote video view.
func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoDecodedOfUid uid: UInt, size: CGSize, elapsed: Int) {
    let userSession = videoSession(of: uid)
    userSession.updateMediaInfo(resolution: size)
    // Set the remote video view.

9. Leave the channel

Call the leaveChannel method to leave the current call according to your scenario, for example, when the call ends, when you need to close the app, or when your app runs in the background.

// Objective-C
[self.rtcEngine setupLocalVideo:nil];
    // Leave the channel.
    [self.rtcEngine leaveChannel:nil];
    if (self.isBroadcaster) {
        [self.rtcEngine stopPreview];
// Swift
func leaveChannel() {       
    // Leave the channel.
    if settings.role == .broadcaster {
    navigationController?.popViewController(animated: true)

Sample code

You can find the sample code logic in the OpenLive-macOS-Objective-C/OpenLive-macOS-Swift demo project.

Run the project

Run the project on your macOS device. When you set the role as the broadcaster and successfully join a video broadcast, you can see the video view of yourself in the app. When you set the role as the audience and successfully join a video broadcast, you can see the video view of the broadcaster in the app.