Skip to main content
Version: 2.0.x

Audience Polls during Live Stream - iOS

Interactive polls are a great way to increase engagement during livestreams. Using VideoSDK’s PubSub mechanism, you can easily implement real-time audience polling, where viewers can vote and see live results instantly.

This guide walks you through how to create, send, and visualize poll results during a livestream.

Step 1: Creating and Publishing a Poll​

The host initiates a poll by publishing a message to the POLL topic using the publish() method of the pubSub property from the Meeting class. The poll message includes a unique identifier, a question, and multiple options. Setting the persist option to true ensures that the poll message is retained and delivered to participants who join the meeting later.

PollHostViewController.swift
import UIKit
import VideoSDKRTC

class PollHostViewController: UIViewController {
var meeting: Meeting!

@IBAction func startPollTapped(_ sender: UIButton) {
let pollData: [String: Any] = [
"id": "\(Date().timeIntervalSince1970)",
"question": "Which feature do you love the most?",
"options": ["Reactions", "Screen Share", "Whiteboard", "Polls"]
]
let options = ["persist": true]
if let pollMessage = try? JSONSerialization.data(withJSONObject: pollData, options: []),
let pollString = String(data: pollMessage, encoding: .utf8) {
meeting.pubSub.publish(topic: "POLL", message: pollString, options: options)
}
}
}

Step 2: Subscribing to Polls and Displaying Options​

Participants subscribe to the POLL topic using the subscribe() method of the pubSub property. Upon receiving a new poll message, they can parse the content and render the voting options dynamically.

import UIKit
import VideoSDKRTC

class PollParticipantViewController: UIViewController, PubSubMessageListener {
var meeting: Meeting!
var currentPoll: [String: Any]?

override func viewDidLoad() {
super.viewDidLoad()
meeting.pubSub.subscribe(topic: "POLL", forListener: self)
}

func onMessageReceived(message: PubSubMessage) {
if let data = message.message.data(using: .utf8),
let poll = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
currentPoll = poll
DispatchQueue.main.async {
self.displayPoll(poll)
}
}
}

func displayPoll(_ poll: [String: Any]) {
// Implement UI to display poll question and options
// For each option, add a button that calls submitVote(option:)
}

func submitVote(option: String) {
guard let pollId = currentPoll?["id"] as? String else { return }
let response: [String: Any] = [
"pollId": pollId,
"option": option
]
if let responseData = try? JSONSerialization.data(withJSONObject: response, options: []),
let responseString = String(data: responseData, encoding: .utf8) {
meeting.pubSub.publish(topic: "POLL_RESPONSE", message: responseString, options: [:])
}
}
}

Step 3: Aggregating and Displaying Poll Results​

The host subscribes to the POLL_RESPONSE topic to collect participants' responses in real-time. By parsing each incoming message, the host can aggregate the results and update the UI accordingly.

import UIKit
import VideoSDKRTC

class PollResultsViewController: UIViewController, PubSubMessageListener {
var meeting: Meeting!
var pollResults: [String: [String: Int]] = [:] // [pollId: [option: count]]

override func viewDidLoad() {
super.viewDidLoad()
meeting.pubSub.subscribe(topic: "POLL_RESPONSE", forListener: self)
}

func onMessageReceived(message: PubSubMessage) {
if let data = message.message.data(using: .utf8),
let response = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let pollId = response["pollId"] as? String,
let option = response["option"] as? String {
var results = pollResults[pollId] ?? [:]
results[option] = (results[option] ?? 0) + 1
pollResults[pollId] = results
DispatchQueue.main.async {
self.updateResultsUI(for: pollId)
}
}
}

func updateResultsUI(for pollId: String) {
// Implement UI update to display poll results
}
}

API Reference​

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord