Create a Basic Audio Conference Application for iOS
This tutorial guides how to create a basic conference application using the iOS SDK.
In order to test the conference call created in this guide, use a physical iOS device when running the app.
Initialize the SDK with your Dolby.io credentials
Initialize the SDK using the secure authentication method that uses a token in the application. For more information, see the Initializing the SDK document. For the purpose of this example, we are using a client access token generated from the Dolby.io dashboard. We recommend creating a new Sample
application for this tutorial.
-
Locate your
Key
andSecret
in your Dolby.io dashboard. The instructions on how to create or find them is in thePrerequisite
section of the Initializing the SDK document. We recommend creating a newSample
application for this tutorial. -
Locate the
AppDelegate.swift
file in your project. -
In the file, change the
application(application, launchOptions)
method as in the following example. Replace theTestClientAccessToken
string with the token generated from the Dolby.io dashboard.
import UIKit
import VoxeetSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the Voxeet SDK
// Please read the documentation at:
// https://docs.dolby.io/communications-apis/docs/initializing-ios
// Generate a client access token from the Dolby.io dashboard and insert into accessToken variable
let accessToken = "ClientAccessToken"
VoxeetSDK.shared.initialize(accessToken: accessToken) { closure, isExpired in
closure(accessToken)
}
// Example of public variables to change the conference behavior.
VoxeetSDK.shared.notification.push.type = .none
VoxeetSDK.shared.conference.defaultBuiltInSpeaker = true
VoxeetSDK.shared.conference.defaultVideo = false
return true
}
}
Open and close a session
To allow creating and joining conferences, log in with a user name. In this tutorial, random user names are assigned.
- In the
ViewController.swift
file, add some variables in theViewController
class to refer to the user interface elements that will be created in step 2.
import VoxeetSDK
class ViewController: UIViewController {
// Session UI.
var sessionTextField: UITextField!
var logInButton: UIButton!
var logoutButton: UIButton!
// User interface settings.
let margin: CGFloat = 16
let buttonWidth: CGFloat = 120
let buttonHeight: CGFloat = 35
let textFieldWidth: CGFloat = 120 + 16 + 120
let textFieldHeight: CGFloat = 40
override func viewDidLoad() {
super.viewDidLoad()
}
}
- In the
ViewController
class, add the following function to create the user interface for the Dolby.io session and assign a random name.
override func viewDidLoad() {
super.viewDidLoad()
initSessionUI()
}
func initSessionUI() {
var statusBarHeight: CGFloat {
// 13.0 and later
if #available(iOS 13.0, *){
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
return window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0;
}else {
return UIApplication.shared.statusBarFrame.height
}
}
let avengersNames = [
"Thor",
"Cap",
"Tony Stark",
"Black Panther",
"Black Widow",
"Hulk",
"Spider-Man",
]
// Session text field.
sessionTextField = UITextField(
frame: CGRect(
x: margin,
y: statusBarHeight + margin,
width: textFieldWidth,
height: textFieldHeight
)
)
sessionTextField.borderStyle = .roundedRect
sessionTextField.placeholder = "Username"
sessionTextField.autocorrectionType = .no
sessionTextField.text = avengersNames.randomElement()
self.view.addSubview(sessionTextField)
// Open session button.
logInButton = UIButton(type: .system) as UIButton
logInButton.frame = CGRect(
x: margin,
y: sessionTextField.frame.origin.y + sessionTextField.frame.height + margin,
width: buttonWidth,
height: buttonHeight
)
logInButton.backgroundColor = logInButton.tintColor
logInButton.layer.cornerRadius = 5
logInButton.isEnabled = true
logInButton.isSelected = true
logInButton.setTitle("LOG IN", for: .normal)
logInButton.addTarget(self, action: #selector(logInButtonAction), for: .touchUpInside)
self.view.addSubview(logInButton)
// Close session button.
logoutButton = UIButton(type: .system) as UIButton
logoutButton.frame = CGRect(
x: logInButton.frame.origin.x + logInButton.frame.width + margin,
y: logInButton.frame.origin.y,
width: buttonWidth,
height: buttonHeight
)
logoutButton.backgroundColor = logoutButton.tintColor
logoutButton.layer.cornerRadius = 5
logoutButton.isEnabled = false
logoutButton.isSelected = true
logoutButton.setTitle("LOGOUT", for: .normal)
logoutButton.addTarget(self, action: #selector(logoutButtonAction), for: .touchUpInside)
self.view.addSubview(logoutButton)
}
- Add methods to log in and log out of the Dolby.io session.
@objc func logInButtonAction(sender: UIButton!) {
// Open participant session.
let info = VTParticipantInfo(name: sessionTextField.text, avatarURL: nil)
VoxeetSDK.shared.session.open(info: info) { error in
self.logInButton.isEnabled = false
self.logoutButton.isEnabled = true
}
}
@objc func logoutButtonAction(sender: UIButton!) {
// Close participant session.
VoxeetSDK.shared.session.close { error in
self.logInButton.isEnabled = true
self.logoutButton.isEnabled = false
}
}
Add a joining option
Add UI for starting a conference in the ViewController.swift
file.
- In the
ViewController.swift
file, add some variables to theViewController
class to refer to the user interface elements that will be created in step 2.
class ViewController: UIViewController {
...
// Conference UI.
var conferenceTextField: UITextField!
var startButton: UIButton!
override func viewDidLoad() {
...
}
}
- Add the following method to extend the user interface for the Dolby.io conference.
override func viewDidLoad() {
...
initSessionUI()
initConferenceUI()
}
...
func initConferenceUI() {
// Session text field.
conferenceTextField = UITextField(
frame: CGRect(
x: margin,
y: logoutButton.frame.origin.y + logoutButton.frame.height + margin,
width: textFieldWidth,
height: textFieldHeight
)
)
conferenceTextField.borderStyle = .roundedRect
conferenceTextField.placeholder = "Conference"
conferenceTextField.autocorrectionType = .no
conferenceTextField.text = "Avengers meeting"
self.view.addSubview(conferenceTextField)
// Conference create/join button.
startButton = UIButton(type: .system) as UIButton
startButton.frame = CGRect(
x: margin,
y: conferenceTextField.frame.origin.y + conferenceTextField.frame.height + margin,
width: buttonWidth,
height: buttonHeight
)
startButton.backgroundColor = startButton.tintColor
startButton.layer.cornerRadius = 5
startButton.isEnabled = false
startButton.isSelected = true
startButton.setTitle("START", for: .normal)
startButton.addTarget(self, action: #selector(startButtonAction), for: .touchUpInside)
self.view.addSubview(startButton)
}
- Enable and disable the start button as appropriate.
@objc func logInButtonAction(sender: UIButton!) {
// Open participant session.
let info = VTParticipantInfo(name: sessionTextField.text, avatarURL: nil)
VoxeetSDK.shared.session.open(info: info) { error in
...
self.startButton.isEnabled = true /* Update start button state */
}
}
@objc func logoutButtonAction(sender: UIButton!) {
// Close participant session.
VoxeetSDK.shared.session.close { error in
...
self.startButton.isEnabled = false /* Update start button state */
}
}
- Add a method to start the Dolby.io conference.
@objc func startButtonAction(sender: UIButton!) {
// Create a conference room with an alias.
let options = VTConferenceOptions()
options.params.dolbyVoice = true
options.alias = conferenceTextField.text ?? ""
VoxeetSDK.shared.conference.create(options: options, success: { conference in
// Join the conference with its id.
VoxeetSDK.shared.conference.join(conference: conference, success: { response in
self.logoutButton.isEnabled = false
self.startButton.isEnabled = false
}, fail: { error in })
}, fail: { error in })
}
Add a leaving option
Add UI for leaving a conference in the ViewController.swift
file.
- In the
ViewController.swift
file, add a variable to theViewController
class to refer to the user interface element that will be created in step 2.
class ViewController: UIViewController {
...
// Conference UI.
...
var leaveButton: UIButton!
...
}
- Modify
initConferenceUI
to extend the user interface for the Dolby.io conference.
func initConferenceUI() {
...
// Conference leave button.
leaveButton = UIButton(type: .system) as UIButton
leaveButton.frame = CGRect(
x: startButton.frame.origin.x + startButton.frame.width + margin,
y: startButton.frame.origin.y,
width: buttonWidth,
height: buttonHeight
)
leaveButton.backgroundColor = leaveButton.tintColor
leaveButton.layer.cornerRadius = 5
leaveButton.isEnabled = false
leaveButton.isSelected = true
leaveButton.setTitle("LEAVE", for: .normal)
leaveButton.addTarget(self, action: #selector(leaveButtonAction), for: .touchUpInside)
self.view.addSubview(leaveButton)
}
- Enable and disable the leave button as appropriate.
@objc func logInButtonAction(sender: UIButton!) {
// Open participant session.
let info = VTParticipantInfo(name: sessionTextField.text, avatarURL: nil)
VoxeetSDK.shared.session.open(info: info) { error in
...
self.leaveButton.isEnabled = false /* Update leave button state */
}
}
@objc func logoutButtonAction(sender: UIButton!) {
// Close participant session.
VoxeetSDK.shared.session.close { error in
...
self.leaveButton.isEnabled = false /* Update leave button state */
}
}
@objc func startButtonAction(sender: UIButton!) {
...
// Join the conference with its id.
VoxeetSDK.shared.conference.join(conference: conference, success: { response in
...
self.leaveButton.isEnabled = true /* Update leave button state */
}, fail: { error in })
}, fail: { error in })
}
- Add a method to leave the Dolby.io conference.
@objc func leaveButtonAction(sender: UIButton!) {
VoxeetSDK.shared.conference.leave { error in
self.logoutButton.isEnabled = true
self.startButton.isEnabled = true
self.leaveButton.isEnabled = false
}
}
Run your application
The app should now build and run.
For reference, the complete contents of the files should be:
AppDelegate.swift
import UIKit
import VoxeetSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the Voxeet SDK
// WARNING: It is best practice to use the VoxeetSDK.shared.initialize(accessToken, refreshTokenClosureWithParam) function to initialize the SDK.
// Please read the documentation at:
// https://docs.dolby.io/communications-apis/docs/initializing-ios
VoxeetSDK.shared.initialize(consumerKey: "YOUR_CONSUMER_KEY", consumerSecret: "YOUR_CONSUMER_SECRET")
// Example of public variables to change the conference behavior.
VoxeetSDK.shared.notification.push.type = .none
VoxeetSDK.shared.conference.defaultBuiltInSpeaker = true
VoxeetSDK.shared.conference.defaultVideo = false
return true
}
}
ViewController.swift
import UIKit
import VoxeetSDK
class ViewController: UIViewController {
// Session UI.
var sessionTextField: UITextField!
var logInButton: UIButton!
var logoutButton: UIButton!
// Conference UI.
var conferenceTextField: UITextField!
var startButton: UIButton!
var leaveButton: UIButton!
// User interface settings.
let margin: CGFloat = 16
let buttonWidth: CGFloat = 120
let buttonHeight: CGFloat = 35
let textFieldWidth: CGFloat = 120 + 16 + 120
let textFieldHeight: CGFloat = 40
override func viewDidLoad() {
super.viewDidLoad()
initSessionUI()
initConferenceUI()
}
func initSessionUI() {
var statusBarHeight: CGFloat {
// 13.0 and later
if #available(iOS 13.0, *){
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
return window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0;
}else {
return UIApplication.shared.statusBarFrame.height
}
}
let avengersNames = [
"Thor",
"Cap",
"Tony Stark",
"Black Panther",
"Black Widow",
"Hulk",
"Spider-Man",
]
// Session text field.
sessionTextField = UITextField(
frame: CGRect(
x: margin,
y: statusBarHeight + margin,
width: textFieldWidth,
height: textFieldHeight
)
)
sessionTextField.borderStyle = .roundedRect
sessionTextField.placeholder = "Username"
sessionTextField.autocorrectionType = .no
sessionTextField.text = avengersNames.randomElement()
self.view.addSubview(sessionTextField)
// Open session button.
logInButton = UIButton(type: .system) as UIButton
logInButton.frame = CGRect(
x: margin,
y: sessionTextField.frame.origin.y + sessionTextField.frame.height + margin,
width: buttonWidth,
height: buttonHeight
)
logInButton.backgroundColor = logInButton.tintColor
logInButton.layer.cornerRadius = 5
logInButton.isEnabled = true
logInButton.isSelected = true
logInButton.setTitle("LOG IN", for: .normal)
logInButton.addTarget(self, action: #selector(logInButtonAction), for: .touchUpInside)
self.view.addSubview(logInButton)
// Close session button.
logoutButton = UIButton(type: .system) as UIButton
logoutButton.frame = CGRect(
x: logInButton.frame.origin.x + logInButton.frame.width + margin,
y: logInButton.frame.origin.y,
width: buttonWidth,
height: buttonHeight
)
logoutButton.backgroundColor = logoutButton.tintColor
logoutButton.layer.cornerRadius = 5
logoutButton.isEnabled = false
logoutButton.isSelected = true
logoutButton.setTitle("LOGOUT", for: .normal)
logoutButton.addTarget(self, action: #selector(logoutButtonAction), for: .touchUpInside)
self.view.addSubview(logoutButton)
}
func initConferenceUI() {
// Session text field.
conferenceTextField = UITextField(
frame: CGRect(
x: margin,
y: logoutButton.frame.origin.y + logoutButton.frame.height + margin,
width: textFieldWidth,
height: textFieldHeight
)
)
conferenceTextField.borderStyle = .roundedRect
conferenceTextField.placeholder = "Conference"
conferenceTextField.autocorrectionType = .no
conferenceTextField.text = "Avengers meeting"
self.view.addSubview(conferenceTextField)
// Conference create/join button.
startButton = UIButton(type: .system) as UIButton
startButton.frame = CGRect(
x: margin,
y: conferenceTextField.frame.origin.y + conferenceTextField.frame.height + margin,
width: buttonWidth,
height: buttonHeight
)
startButton.backgroundColor = startButton.tintColor
startButton.layer.cornerRadius = 5
startButton.isEnabled = false
startButton.isSelected = true
startButton.setTitle("START", for: .normal)
startButton.addTarget(self, action: #selector(startButtonAction), for: .touchUpInside)
self.view.addSubview(startButton)
// Conference leave button.
leaveButton = UIButton(type: .system) as UIButton
leaveButton.frame = CGRect(
x: startButton.frame.origin.x + startButton.frame.width + margin,
y: startButton.frame.origin.y,
width: buttonWidth,
height: buttonHeight
)
leaveButton.backgroundColor = leaveButton.tintColor
leaveButton.layer.cornerRadius = 5
leaveButton.isEnabled = false
leaveButton.isSelected = true
leaveButton.setTitle("LEAVE", for: .normal)
leaveButton.addTarget(self, action: #selector(leaveButtonAction), for: .touchUpInside)
self.view.addSubview(leaveButton)
}
@objc func logInButtonAction(sender: UIButton!) {
// Open participant session.
let info = VTParticipantInfo(externalID: nil, name: sessionTextField.text, avatarURL: nil)
VoxeetSDK.shared.session.open(info: info) { error in
self.logInButton.isEnabled = false
self.logoutButton.isEnabled = true
self.startButton.isEnabled = true
self.leaveButton.isEnabled = false
}
}
@objc func logoutButtonAction(sender: UIButton!) {
// Close participant session.
VoxeetSDK.shared.session.close { error in
self.logInButton.isEnabled = true
self.logoutButton.isEnabled = false
self.startButton.isEnabled = false
self.leaveButton.isEnabled = false
}
}
@objc func startButtonAction(sender: UIButton!) {
// Create a conference room with an alias.
let options = VTConferenceOptions()
options.params.dolbyVoice = true
options.alias = conferenceTextField.text ?? ""
VoxeetSDK.shared.conference.create(options: options, success: { conference in
// Join the conference with its id.
VoxeetSDK.shared.conference.join(conference: conference, success: { response in
self.logoutButton.isEnabled = false
self.startButton.isEnabled = false
self.leaveButton.isEnabled = true
}, fail: { error in })
}, fail: { error in })
}
@objc func leaveButtonAction(sender: UIButton!) {
VoxeetSDK.shared.conference.leave { error in
self.logoutButton.isEnabled = true
self.startButton.isEnabled = true
self.leaveButton.isEnabled = false
}
}
}
Updated 4 months ago