People engage longer when they see, hear, and interact with each other. The Agora SDK enables you to embed real-time voice and video interaction in any app, on any device, anywhere.
This page shows the minimum code you need to integrate high-quality, low-latency live streaming experience into your app using the Agora Video SDK for iOS.
The following figure shows the workflow to integrate into your app in order to add Interactive Live Streaming Standard functionality.
As shown in the figure, the workflow for adding Interactive Live Streaming Standard in your project is as follows:
Set the client role and latency level
Each user in an Interactive Live Streaming Standard channel is either a host or an audience member. Hosts publish streams to the channel, and the audience subscribe to the streams. When a user is an audience member, you can control the delay the user receives host streams using ClientRoleOptions
.
Retrieve a token
A token is the credential that authenticates a user when your app client joins a channel. In a test or production environment, your app client retrieves tokens from a server in your security infrastructure.
Join a channel
Call joinChannel
to create and join a channel. App clients that pass the same channel name join the same channel.
Publish and subscribe to audio and video in the channel
After joining a channel, app clients with the role of the host can publish audio and video. For an auidence memeber to send audio and video, call setClientRole
to switch the client role.
For an app client to join a channel, you need the following information:
Before proceeding, ensure that your development environment meets the following requirements:
In Xcode, follow the steps to create the environment necessary to add Interactive Live Streaming Standard into your app.
Integrate the Video SDK into your project:
Go to File > Swift Packages > Add Package Dependencies..., and paste the following URL:
https://github.com/AgoraIO/AgoraRtcEngine_iOS
In Choose Package Options, specify the Video SDK version you want to use. You need to fill in x.y.z for version x.y.z and x.y.z-r.a for version x.y.z.a. For example, fill in 3.5.0 for version 3.5.0 and 3.5.0-r.2 for version 3.5.0.2.
info.plist
file of your project and add the following properties:This section shows how to use the Agora Video SDK to implement Interactive Live Streaming Standard into your app step by step.
In the interface, you should have one frame for local video and another for remote video. In ViewController.swift
, replace any existing content with the following:
import UIKit
class ViewController: UIViewController {
var localView: UIView!
var remoteView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
initView()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
remoteView.frame = self.view.bounds
localView.frame = CGRect(x: self.view.bounds.width - 90, y: 0, width: 90, height: 160)
}
func initView() {
remoteView = UIView()
self.view.addSubview(remoteView)
localView = UIView()
self.view.addSubview(localView)
}
}
When your app opens, you create an RtcEngine
instance, enable the video, join a channel, and if the local user is a host, publish the local video to the lower frame layout in the UI. When another host joins the channel, your app catches the join event and adds the remote video to the top frame layout in the UI.
The following figure shows the API call sequence of implementing Interactive Live Streaming Standard.
To implement this logic, take the following steps:
Import the Agora kit and add the agoraKit
variable.
Modify your ViewController.swift
as follows:
import UIKit
// Add this line to import the Agora kit
import AgoraRtcKit
class ViewController: UIViewController {
var localView: UIView!
var remoteView: UIView!
// Add this linke to add the agoraKit variable
var agoraKit: AgoraRtcEngineKit?
}
override func viewDidLoad() {
super.viewDidLoad()
initView()
}
Initialize the app and join the channel.
Call the core methods to initialize the app and join a channel. In this example app, this functionality is encapsulated in the initializeAndJoinChannel
function.
In ViewController.swift
, add the following lines after the initView
function, and fill in your App ID, temporary token, and channel name:
func initializeAndJoinChannel() {
// Pass in your App ID here
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "Your App ID", delegate: self)
// For a live streaming scenario, set the channel profile as liveBroadcasting.
agoraKit?.setChannelProfile(.liveBroadcasting)
// Set the client role as audience and the latency level as low latency.
let options: AgoraClientRoleOptions = AgoraClientRoleOptions()
options.audienceLatencyLevel = AgoraAudienceLatencyLevelType.lowLatency
agoraKit?.setClientRole(.audience, options: options)
// Video is disabled by default. You need to call enableVideo to start a video stream.
agoraKit?.enableVideo()
// Join the channel with a token. Pass in your token and channel name here
agoraKit?.joinChannel(byToken: "Your token", channelId: "Channel name", info: nil, uid: 0, joinSuccess: { (channel, uid, elapsed) in
})
}
Add the remote interface when a remote host joins the channel.
In ViewController.swift
, add the following lines after the ViewController
class:
extension ViewController: AgoraRtcEngineDelegate {
// This callback is triggered when a remote host joins the channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.renderMode = .hidden
videoCanvas.view = remoteView
agoraKit?.setupRemoteVideo(videoCanvas)
}
}
Now you have created the Interactive Live Streaming Standard functionality, start and stop the app. In this implementation, a live stream starts when the user opens your app. The live stream ends when the user closes your app.
To implement the functionality of starting and stopping the app, do the following:
Check that the app has the correct permissions. If permissions are granted, call initializeAndJoinChannel
to join a live streaming channel.
When the view is loaded, call initializeAndJoinChannel
to join a live streaming channel.
In ViewController.swift
, add the initializeAndJoinChannel
function inside the viewDidLoad
function:
override func viewDidLoad() {
super.viewDidLoad()
initView()
// Add this line
initializeAndJoinChannel()
}
When the user closes this app, clean up all the resources used by your app.
In ViewController.swift
, add viewDidDisappear
after the initializeAndJoinChannel
function.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
agoraKit?.leaveChannel(nil)
AgoraRtcEngineKit.destroy()
}
To test your app on a physical device, do the following:
ViewController.swift
.Generating a token by hand is not helpful in a production context. Authenticate Your Users with Tokens shows you how to start live streaming with a token that you retrieve from your server.
This section provides additional information for your reference.
In addition to integrating the Agora Video SDK for iOS through Swift Package, you can also import the SDK into your project through CocoaPods or by manually copying the SDK files.
Automatically integrate the SDK with CocoaPods
Install CocoaPods if you have not. See Getting Started with CocoaPods.
In Terminal, navigate to the root of your project folder, and run the pod init
command to create a Podfile
in the project folder.
Open the Podfile
, and replace all contents with the following code. Remember to replace Your App
with the target name of your project.
# platform :ios, '9.0'
target 'Your App' do
pod 'AgoraRtcEngine_iOS'
end
pod install
command to install the SDK. When the SDK is installed successfully, you can see Pod installation complete!
in Terminal and an xcworkspace
file in the project folder.xcworkspace
file for any further steps.Manually copy the SDK files
libs
folder of the downloaded SDK package, copy the files or subfolders you need to the root of your project folder.In Xcode, link your target to the frameworks or libraries you have copied. Be sure to choose Embed & Sign from the pop-up menu in the Embed column.
To implement live streaming in your app using Objective-C:
Replace the contents in the ViewController.h
file with the following:
#import <UIKit/UIKit.h>
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
@interface ViewController : UIViewController <AgoraRtcEngineDelegate>
@property (strong, nonatomic) AgoraRtcEngineKit *agoraKit;
@end
Replace the contents in the ViewController.m
file with the following:
#import "ViewController.h"
#import <UIKit/UIKit.h>
@interface ViewController ()
@property (nonatomic, strong) UIView *localView;
@property (nonatomic, strong) UIView *remoteView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initViews];
[self initializeAndJoinChannel];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.remoteView.frame = self.view.bounds;
self.localView.frame = CGRectMake(self.view.bounds.size.width - 90, 0, 90, 160);
}
- (void)initViews {
self.remoteView = [[UIView alloc] init];
[self.view addSubview:self.remoteView];
self.localView = [[UIView alloc] init];
[self.view addSubview:self.localView];
}
- (void)initializeAndJoinChannel {
// Pass in your App ID here
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:@"Your App ID" delegate:self];
[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
AgoraClientRoleOptions *options = [AgoraClientRoleOptions alloc];
options.audienceLatencyLevel = AgoraAudienceLatencyLevelLowLatency;
[self.agoraKit setClientRole:AgoraClientRoleAudience options:options];
[self.agoraKit enableVideo];
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = 0;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
videoCanvas.view = self.localView;
[self.agoraKit setupLocalVideo:videoCanvas];
// Pass in your token and channel name here
[self.agoraKit joinChannelByToken:@"Your token" channelId:@"Channel name" info:nil uid:0 joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
}];
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = uid;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
videoCanvas.view = self.remoteView;
[self.agoraKit setupRemoteVideo:videoCanvas];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.agoraKit leaveChannel:nil];
[AgoraRtcEngineKit destroy];
}
@end
Choose one of the following methods to integrate a version of the Agora iOS SDK earlier than v3.2.0.
Method 1: Through CocoaPods
Ensure that you have installed CocoaPods before performing the following steps. See the installation guide in Getting Started with CocoaPods.
In Terminal, navigate to the project path, and run the pod init
command to create a Podfile
in the project folder.
Open the Podfile
, delete all contents, and input the following codes. Remember to replace Your App
with the target name of your project and replace version
with the version of the SDK that you want to integrate. For information about the SDK version, see Release Notes.
# platform :ios, '9.0'
target 'Your App' do
pod 'AgoraRtcEngine_iOS', 'version'
end
Return to Terminal, and 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.
Open the generated xcworkspace
file.
Method 2: Through your local storage
You need to use different integration methods to integrate different versions of the SDK. Click the following version categories to expand the corresponding integration steps.
According to your requirements, choose one of the following methods to copy the AgoraRtcKit.framework
, Agorafdkaac.framework
, Agoraffmpeg.framework
, and AgoraSoundTouch.framework
dynamic libraries to the ./project_name
folder in your project (project_name
is an example of your project name):
a. If you do not need to use a simulator to run the project, copy the above dynamic libraries under the path of ./libs
in the SDK package.
b. If you need to use a simulator to run the project, copy the above dynamic libraries under the path of ./libs/ALL_ARCHITECTURE
in the SDK package. The dynamic libraries under this path contains the x86-64 architecture, which affects the distribution of your app in the App Store. See solutions in Distribution consideration.
Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
, Agorafdkaac.framework
, Agoraffmpeg.framework
, and AgoraSoundTouch.framework
dynamic libraries. Ensure that the Embed attribute of these dynamic libraries is Embed & Sign.
Once these dynamic libraries are added, the project automatically links to other system libraries.
According to your requirements, choose one of the following methods to copy the AgoraRtcKit.framework
dynamic library to the ./project_name
folder in your project (project_name
is an example of your project name):
a. If you do not need to use a simulator to run the project, copy the above dynamic library under the path of ./libs
in the SDK package.
b. If you need to use a simulator to run the project, copy the above dynamic library under the path of ./libs/ALL_ARCHITECTURE
in the SDK package. The dynamic libraries under this path contains the x86-64 and i386 architectures, which affects the distribution of your app in the App Store. See solutions in Distribution consideration.
Open Xcode, and navigate to TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content.
Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
dynamic library. Ensure that the Embed attribute of the dynamic library is Embed & Sign. Once the dynamic library is added, the project automatically links to other system libraries.
In v3.0.0, the SDK package contains an AgoraRtcKit.framework
dynamic library and an AgoraRtcKit.framework
static library. Choose which of these libraries to add according to your needs.
The paths of the two libraries in the SDK package are as follows:
./Agora_Native_SDK_for_iOS_..._Dynamic/libs
../Agora_Native_SDK_for_iOS_.../libs
.Integrate the dynamic library:
Copy the AgoraRtcKit.framework
dynamic library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).
Open Xcode, and navigate to TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content.
Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
dynamic library. Ensure that the Embed attribute of the dynamic library is Embed & Sign.
Once the dynamic library is added, the project automatically links to other system libraries.
Integrate the static library:
AgoraRtcKit.framework
static library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).AgoraRtcKit.framework
static library, you need to click +, and then click Add Other....SDK | Library |
---|---|
Voice SDK | AgoraRtcKit.framework Accelerate.framework AudioToolbox.framework AVFoundation.framework CoreMedia.framework libc++.tbd libresolv.tbd SystemConfiguration.framework CoreTelephony.framework |
Video SDK | AgoraRtcKit.framework Accelerate.framework AudioToolbox.framework AVFoundation.framework CoreMedia.framework libc++.tbd libresolv.tbd SystemConfiguration.framework CoreML.framework VideoToolbox.framework |
AgoraRtcEngineKit.framework
static library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).AgoraRtcEngineKit.framework
static library, you need to click +, and then click Add Other....SDK | Library |
---|---|
Voice SDK | AgoraRtcEngineKit.framework Accelerate.framework AudioToolbox.framework AVFoundation.framework CoreMedia.framework libc++.tbd libresolv.tbd SystemConfiguration.framework CoreTelephony.framework |
Video SDK | AgoraRtcEngineKit.framework Accelerate.framework AudioToolbox.framework AVFoundation.framework CoreMedia.framework libc++.tbd libresolv.tbd SystemConfiguration.framework CoreML.framework VideoToolbox.framework |
If you integrate dynamic libraries under the path of ./libs/ALL_ARCHITECTURE
in the SDK package, you need to remove the x86-64 architecture in the libraries before uploading the app to the App Store.
In Terminal, run the following command to remove the x86-64 architecture. Remember to replace ALL_ARCHITECTURE/AgoraRtcKit.framework/AgoraRtcKit
with the path of the dynamic library in your project.
lipo -remove x86-64 ALL_ARCHITECTURE/AgoraRtcKit.framework/AgoraRtcKit -output ALL_ARCHITECTURE/AgoraRtcKit.framework/AgoraRtcKit
See more considerations in Preparing Your App for Distribution.