⚠️ Sunset Notice: This service will be discontinued as of September 30th, 2023. Learn more »
Did you come here for Live Video Shopping?
This is documentation for Bambuser Live Streaming SDK.
If you're looking for documentation regarding Live Video Shopping (opens new window) , see these pages (opens new window)
How to create a live broadcasting app in Swift using Xcode
This guide is based on Xcode 12.5.
This guide focuses on the bare minimum required to start broadcasting. Make sure to familiarize yourself with the example apps in the SDK bundles for a more complete overview.
Create a new Application
Open Xcode.
Select File -> New -> Project...
Choose the App template.
Enter a suitable product name and add your team and your organization identifier
Ensure Swift is the selected language. Or see the Objective C guide if you prefer Objective C.
Add dependencies
Installing dependencies using Swift Package Manager
You can use Swift Package Manager to install the Bambuser SDK:s.
Add
https://github.com/bambuser/bambuser-sdk-ios
to your Xcode project orPackage.swift
file.Select the
1.0.4
version to get the latest SDK:s.Xcode will then update the SDK:s automatically, depending on the version rule you choose
Installing dependencies using CocoaPods
If your development environment is set up for it, you can use CocoaPods (opens new window) to install the Bambuser SDK:s.
Prepare the newly created project for CocoaPods use with
pod init
.Add
pod 'libbambuser-ios', '1.0.4'
to your Podfile.Run
pod install
to fetch the SDK and configure the project.
Install dependencies manually
The Bambuser broadcasting library has the following dependencies:
libz.tbd
,libc++.tbd
AudioToolbox
,AVFoundation
,CoreGraphics
,CoreLocation
,CoreMedia
,CoreTelephony
,CoreVideo
,Foundation
,QuartzCore
,SystemConfiguration
,UIKit
,VideoToolbox

Add the broadcast SDK
Log in to the Bambuser site and download the latest iOS SDK bundle from the Developer (opens new window) page.
Open up Finder and navigate to the download folder, then double click the SDK bundle to unzip it.
Go to the
Frameworks
directory in the SDK bundle and dragBambuserBroadcaster.xcframework
into the Frameworks section of your Xcode project's file tree navigator.

- Check Copy items if needed to ensure that your project folder gets its own copy of the files.

- The act of adding
BambuserBroadcaster.xcframework
intoFrameworks
should also have addedBambuserBroadcaster.xcframework
toFrameworks, Libraries and Embedded Content
underGeneral
.
Enable camera and microphone access
Your app will not be allowed to access the camera or microphone unless its
Info.plist
file contains entries for Privacy - Camera Usage Description
and Privacy - Microphone Usage Description.
Double-click Info.plist
to bring up the editor and add them to the bottom
of the list.

Bootstrap the SDK
Now that you have installed the dependencies it's time to start using the SDK.
In ViewController.swift
import BambuserBroadcaster
and add a variable of the type BambuserView (opens new window) to your ViewController class.
import BambuserBroadcaster
class ViewController: UIViewController, BambuserViewDelegate {
var bambuserView : BambuserView
...
In ViewController.swift
override the init function of ViewController
class to
initialize our new variable. BambuserView (opens new window) requires a preset, kSessionPresetAuto
is optimal for most apps.
required init?(coder aDecoder: NSCoder) {
bambuserView = BambuserView(preparePreset: kSessionPresetAuto)
super.init(coder: aDecoder)
}
Add the viewfinder
In ViewController.swift
in the viewDidLoad
method, add the viewfinder
to the view hierarchy and ensure it is rotated correctly.
bambuserView.orientation = UIApplication.shared.statusBarOrientation
self.view.addSubview(bambuserView.view)
In ViewController.swift
override the viewWillLayoutSubviews
method, then add
some code to ensure the viewfinder is assigned the desired dimensions.
override func viewWillLayoutSubviews() {
var statusBarOffset : CGFloat = 0.0
statusBarOffset = CGFloat(self.topLayoutGuide.length)
bambuserView.previewFrame = CGRect(x: 0.0, y: 0.0 + statusBarOffset, width: self.view.bounds.size.width, height: self.view.bounds.size.height - statusBarOffset)
}
Start capturing frames
After all settings to BambuserView
has been done, add a call to startCapture
in the viewDidLoad
method.
bambuserView.startCapture()
Authentication
To be able to broadcast, your app needs to identify itself to Bambuser.
Head over to the Developer (opens new window) page on the
Bambuser site again and get the Sandbox applicationId,
then assign it to BambuserView (opens new window) in ViewController.swift
directly after initialization.
WARNING
Remember to replace the Sandbox id with a Production applicationId before you release your app!
bambuserView.applicationId = "GFZalqkR5iyZcIgaolQmA"
Add a broadcasting button
Let's add a simple button to be able to control the broadcast start and stop triggers.
In ViewController.swift
, add a variable of the type UIButton:
class ViewController: UIViewController {
var bambuserView : BambuserView
var broadcastButton : UIButton
In ViewController.swift
, initialize the button in the init
method.
broadcastButton = UIButton(type: UIButton.ButtonType.system)
In ViewController.swift
, set up the button in the viewDidLoad method
and add it to the view hierarchy.
broadcastButton.addTarget(self, action: #selector(ViewController.broadcast), for: UIControl.Event.touchUpInside)
broadcastButton.setTitle("Broadcast", for: UIControl.State.normal)
self.view.addSubview(broadcastButton)
In ViewController.swift
, in the viewWillLayoutSubviews
method, position
the button to taste
broadcastButton.frame = CGRect(x: 0.0, y: 0.0 + statusBarOffset, width: 100.0, height: 50.0);
Also add a new method to handle button taps
@objc func broadcast() {
NSLog("Starting broadcast")
broadcastButton.setTitle("Connecting", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(bambuserView, action: #selector(bambuserView.stopBroadcasting), for: UIControl.Event.touchUpInside)
bambuserView.startBroadcasting()
}
Subscribe to events
To know what's going on inside BambuserView (opens new window), we should hook up ourself as
its delegate. In ViewController.swift
, assign self
to bambuserView.delegate
directly after initializing our superclass:
bambuserView.delegate = self;
In ViewController.swift
, we now need to declare that our class supports the
BambuserViewDelegate (opens new window) protocol:
class ViewController: UIViewController, BambuserViewDelegate {
Finally, we add a few callback methods in ViewController.swift
:
func broadcastStarted() {
NSLog("Received broadcastStarted signal")
broadcastButton.setTitle("Stop", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(bambuserView, action: #selector(bambuserView.stopBroadcasting), for: UIControl.Event.touchUpInside)
}
func broadcastStopped() {
NSLog("Received broadcastStopped signal")
broadcastButton.setTitle("Broadcast", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(self, action: #selector(ViewController.broadcast), for: UIControl.Event.touchUpInside)
}
Configuring AVAudioSession
Since iOS 14.5 there is an option to prevent the system from interrupting the audio session at an incoming
call notification (and thereby interrupting the broadcast), by setting AVAudioSession.sharedInstance().setPrefersNoInterruptionsFromSystemAlerts()
to true
.
Note! This is only effective if the user has selected Banner notification display style (Settings - Phone - Incoming calls).
Putting it all together
The above steps should lead to a main view source somewhat along these lines:
ViewController.swift
import UIKit
import BambuserBroadcaster
class ViewController: UIViewController, BambuserViewDelegate {
var bambuserView : BambuserView
var broadcastButton : UIButton
required init?(coder aDecoder: NSCoder) {
if #available(iOS 14.5, *) {
do {
try AVAudioSession.sharedInstance().setPrefersNoInterruptionsFromSystemAlerts(true)
} catch {
}
}
bambuserView = BambuserView(preparePreset: kSessionPresetAuto)
broadcastButton = UIButton(type: UIButton.ButtonType.system)
super.init(coder: aDecoder)
bambuserView.delegate = self
bambuserView.applicationId = "GFZalqkR5iyZcIgaolQmA"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
bambuserView.orientation = UIApplication.shared.statusBarOrientation
self.view.addSubview(bambuserView.view)
bambuserView.startCapture()
broadcastButton.addTarget(self, action: #selector(ViewController.broadcast), for: UIControl.Event.touchUpInside)
broadcastButton.setTitle("Broadcast", for: UIControl.State.normal)
self.view.addSubview(broadcastButton)
}
override func viewWillLayoutSubviews() {
var statusBarOffset : CGFloat = 0.0
statusBarOffset = CGFloat(self.topLayoutGuide.length)
bambuserView.previewFrame = CGRect(x: 0.0, y: 0.0 + statusBarOffset, width: self.view.bounds.size.width, height: self.view.bounds.size.height - statusBarOffset)
broadcastButton.frame = CGRect(x: 0.0, y: 0.0 + statusBarOffset, width: 100.0, height: 50.0);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func broadcast() {
NSLog("Starting broadcast")
broadcastButton.setTitle("Connecting", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(bambuserView, action: #selector(bambuserView.stopBroadcasting), for: UIControl.Event.touchUpInside)
bambuserView.startBroadcasting()
}
func broadcastStarted() {
NSLog("Received broadcastStarted signal")
broadcastButton.setTitle("Stop", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(bambuserView, action: #selector(bambuserView.stopBroadcasting), for: UIControl.Event.touchUpInside)
}
func broadcastStopped() {
NSLog("Received broadcastStopped signal")
broadcastButton.setTitle("Broadcast", for: UIControl.State.normal)
broadcastButton.removeTarget(nil, action: nil, for: UIControl.Event.touchUpInside)
broadcastButton.addTarget(self, action: #selector(ViewController.broadcast), for: UIControl.Event.touchUpInside)
}
}
Testing in the simulator
Since the iOS Simulator does not feature a camera, what you can do there is limited.
Testing on a device
How to configure Xcode for ad-hoc development is out of scope for this guide. Assuming you have all the required privileges, you should be able to tether your iOS device to Xcode and click run.
If everything is set up correctly, you should be able to start your first broadcast by tapping the button we added earlier.
Check the Bambuser site when logged in for a notification and web preview when you go live in Sandbox mode.

This is how it looks on the phone

Tap the button to start a broadcast.
Screenshot 1-2: The first time, iOS asks the user for camera and microphone access.
Screenshot 3: Then the broadcast is running and the button turns into a stop button.
Screenshot 4: Finally, we tap the button again and return to the non-broadcasting state.
What's next
Be sure to experience a few of your live broadcasts via the Sandbox player on the Bambuser website.
Consider whether you also need a player in your app and / or on your website.
Study the REST APIs (opens new window) and Webhooks, which can be used to make your backend broadcast-aware.