Activity Feeds V3 is in closed alpha β€” do not use it in production (just yet).

Event Handling

This document explains how to listen to real-time events from Stream Feeds using the FeedsClient event publisher.

Overview

The FeedsClient provides two ways to listen to events:

  1. All Events: Listen to all events and handle them with type checking
  2. Specific Event Types: Listen to only specific event types for type-safe handling

Listening to All Events

Use the main eventPublisher to receive all events and handle them with type checking:

import Combine
import StreamFeeds

class MyViewController: UIViewController {
    @State private var cancellables = Set<AnyCancellable>()
    let feedsClient: FeedsClient

    override func viewDidLoad() {
        super.viewDidLoad()
        setupEventListening()
    }

    private func setupEventListening() {
        feedsClient.eventPublisher
            .sink { event in
                self.handleEvent(event)
            }
            .store(in: &cancellables)
    }

    private func handleEvent(_ event: Event) {
        switch event {
        case let activityEvent as ActivityAddedEvent:
            print("πŸ“ New activity: \(activityEvent.activity.id)")
            updateFeedUI()

        case let pollEvent as PollClosedFeedEvent:
            print("πŸ“Š Poll closed: \(pollEvent.poll.id)")
            refreshPollData()

        case let commentEvent as CommentAddedEvent:
            print("πŸ’¬ New comment: \(commentEvent.comment.id)")
            updateCommentsUI()

        case let reactionEvent as ActivityReactionAddedEvent:
            print("πŸ‘ Reaction added: \(reactionEvent.reaction.kind)")
            updateReactionsUI()

        case let followEvent as FollowCreatedEvent:
            print("πŸ‘₯ New follow: \(followEvent.follow.target)")
            updateFollowCount()

        case let bookmarkEvent as BookmarkAddedEvent:
            print("πŸ”– Bookmark added: \(bookmarkEvent.bookmark.id)")
            updateBookmarksUI()

        case let feedEvent as FeedCreatedEvent:
            print("πŸ“‹ Feed created: \(feedEvent.fid)")
            refreshFeedList()

        case let connectedEvent as ConnectedEvent:
            print("πŸ”— Connected to Stream with ID: \(connectedEvent.connectionId)")

        case let errorEvent as ConnectionErrorEvent:
            print("❌ Connection error: \(errorEvent.error)")
            handleConnectionError()

        default:
            print("πŸ“‘ Received event: \(type(of: event))")
        }
    }
}

Listening to Specific Event Types

For type-safe event handling, use the generic eventPublisher(for:) method:

class ActivityHandler {
    private var cancellables = Set<AnyCancellable>()
    let feedsClient: FeedsClient

    init(feedsClient: FeedsClient) {
        self.feedsClient = feedsClient
        setupActivityListeners()
    }

    private func setupActivityListeners() {
        // Listen only to activity added events
        feedsClient.eventPublisher(for: ActivityAddedEvent.self)
            .sink { activityEvent in
                print("New activity: \(activityEvent.activity.id)")
                self.handleNewActivity(activityEvent)
            }
            .store(in: &cancellables)

        // Listen only to activity updated events
        feedsClient.eventPublisher(for: ActivityUpdatedEvent.self)
            .sink { activityEvent in
                print("Activity updated: \(activityEvent.activity.id)")
                self.handleActivityUpdate(activityEvent)
            }
            .store(in: &cancellables)

        // Listen only to activity deleted events
        feedsClient.eventPublisher(for: ActivityDeletedEvent.self)
            .sink { activityEvent in
                print("Activity deleted: \(activityEvent.activity.id)")
                self.handleActivityDeletion(activityEvent)
            }
            .store(in: &cancellables)
    }

    private func handleNewActivity(_ event: ActivityAddedEvent) {
        // Handle new activity
    }

    private func handleActivityUpdate(_ event: ActivityUpdatedEvent) {
        // Handle activity update
    }

    private func handleActivityDeletion(_ event: ActivityDeletedEvent) {
        // Handle activity deletion
    }
}

Multiple Event Type Listeners

You can set up multiple listeners for different event types:

class FeedManager {
    private var cancellables = Set<AnyCancellable>()
    let feedsClient: FeedsClient

    init(feedsClient: FeedsClient) {
        self.feedsClient = feedsClient
        setupEventListeners()
    }

    private func setupEventListeners() {
        // Activity events
        feedsClient.eventPublisher(for: ActivityAddedEvent.self)
            .sink { [weak self] event in
                self?.handleActivityAdded(event)
            }
            .store(in: &cancellables)

        // Comment events
        feedsClient.eventPublisher(for: CommentAddedEvent.self)
            .sink { [weak self] event in
                self?.handleCommentAdded(event)
            }
            .store(in: &cancellables)

        // Poll events
        feedsClient.eventPublisher(for: PollVoteCastedFeedEvent.self)
            .sink { [weak self] event in
                self?.handlePollVote(event)
            }
            .store(in: &cancellables)

        // Connection events
        feedsClient.eventPublisher(for: ConnectedEvent.self)
            .sink { [weak self] event in
                self?.handleConnection(event)
            }
            .store(in: &cancellables)
    }
}

SwiftUI Integration

Here’s how to listen to events in SwiftUI:

struct FeedView: View {
    @StateObject private var viewModel: FeedViewModel
    @State private var cancellables = Set<AnyCancellable>()

    var body: some View {
        List(viewModel.activities) { activity in
            ActivityRow(activity: activity)
        }
        .onAppear {
            setupEventListening()
        }
        .onDisappear {
            cancellables.removeAll()
        }
    }

    private func setupEventListening() {
        viewModel.feedsClient.eventPublisher(for: ActivityAddedEvent.self)
            .receive(on: DispatchQueue.main)
            .sink { event in
                viewModel.addActivity(event.activity)
            }
            .store(in: &cancellables)

        viewModel.feedsClient.eventPublisher(for: ActivityUpdatedEvent.self)
            .receive(on: DispatchQueue.main)
            .sink { event in
                viewModel.updateActivity(event.activity)
            }
            .store(in: &cancellables)
    }
}

Available Event Types

Below is a comprehensive table of all available event types and their descriptions:

Event NameDescription
Activity Events
ActivityAddedEventFired when a new activity is added to a feed
ActivityUpdatedEventFired when an activity is modified
ActivityDeletedEventFired when an activity is removed
ActivityRemovedFromFeedEventFired when an activity is removed from a specific feed
ActivityMarkEventFired when activities are marked as read/seen
ActivityPinnedEventFired when an activity is pinned to the top
ActivityUnpinnedEventFired when an activity is unpinned
Comment Events
CommentAddedEventFired when a new comment is added to an activity
CommentUpdatedEventFired when a comment is modified
CommentDeletedEventFired when a comment is removed
Reaction Events
ActivityReactionAddedEventFired when a reaction is added to an activity
ActivityReactionDeletedEventFired when a reaction is removed from an activity
CommentReactionAddedEventFired when a reaction is added to a comment
CommentReactionDeletedEventFired when a reaction is removed from a comment
Poll Events
PollClosedFeedEventFired when a poll is closed
PollDeletedFeedEventFired when a poll is deleted
PollUpdatedFeedEventFired when a poll is modified
PollVoteCastedFeedEventFired when a vote is cast
PollVoteChangedFeedEventFired when a vote is changed
PollVoteRemovedFeedEventFired when a vote is removed
Feed Events
FeedCreatedEventFired when a new feed is created
FeedUpdatedEventFired when a feed is modified
FeedDeletedEventFired when a feed is deleted
FeedGroupChangedEventFired when a feed group is modified
FeedGroupDeletedEventFired when a feed group is deleted
Member Events
FeedMemberAddedEventFired when a member is added to a feed
FeedMemberRemovedEventFired when a member is removed from a feed
FeedMemberUpdatedEventFired when a member’s role/permissions change
Follow Events
FollowCreatedEventFired when a follow relationship is created
FollowDeletedEventFired when a follow relationship is removed
FollowUpdatedEventFired when follow settings are modified
Bookmark Events
BookmarkAddedEventFired when an activity is bookmarked
BookmarkDeletedEventFired when a bookmark is removed
BookmarkUpdatedEventFired when bookmark metadata is modified
Connection Events
ConnectedEventFired when successfully connected to WebSocket
ConnectionErrorEventFired when connection fails or errors occur
HealthCheckEventFired when health check is received
Β© Getstream.io, Inc. All Rights Reserved.