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))")
        }
    }
}Activity Feeds v3 is in beta β try it out!
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:
- All Events: Listen to all events and handle them with type checking
 - 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:
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 Name | Description | 
|---|---|
| Activity Events | |
ActivityAddedEvent | Fired when a new activity is added to a feed | 
ActivityUpdatedEvent | Fired when an activity is modified | 
ActivityDeletedEvent | Fired when an activity is removed | 
ActivityRemovedFromFeedEvent | Fired when an activity is removed from a specific feed | 
ActivityMarkEvent | Fired when activities are marked as read/seen | 
ActivityPinnedEvent | Fired when an activity is pinned to the top | 
ActivityUnpinnedEvent | Fired when an activity is unpinned | 
| Comment Events | |
CommentAddedEvent | Fired when a new comment is added to an activity | 
CommentUpdatedEvent | Fired when a comment is modified | 
CommentDeletedEvent | Fired when a comment is removed | 
| Reaction Events | |
ActivityReactionAddedEvent | Fired when a reaction is added to an activity | 
ActivityReactionDeletedEvent | Fired when a reaction is removed from an activity | 
CommentReactionAddedEvent | Fired when a reaction is added to a comment | 
CommentReactionDeletedEvent | Fired when a reaction is removed from a comment | 
| Poll Events | |
PollClosedFeedEvent | Fired when a poll is closed | 
PollDeletedFeedEvent | Fired when a poll is deleted | 
PollUpdatedFeedEvent | Fired when a poll is modified | 
PollVoteCastedFeedEvent | Fired when a vote is cast | 
PollVoteChangedFeedEvent | Fired when a vote is changed | 
PollVoteRemovedFeedEvent | Fired when a vote is removed | 
| Feed Events | |
FeedCreatedEvent | Fired when a new feed is created | 
FeedUpdatedEvent | Fired when a feed is modified | 
FeedDeletedEvent | Fired when a feed is deleted | 
FeedGroupChangedEvent | Fired when a feed group is modified | 
FeedGroupDeletedEvent | Fired when a feed group is deleted | 
| Member Events | |
FeedMemberAddedEvent | Fired when a member is added to a feed | 
FeedMemberRemovedEvent | Fired when a member is removed from a feed | 
FeedMemberUpdatedEvent | Fired when a memberβs role/permissions change | 
| Follow Events | |
FollowCreatedEvent | Fired when a follow relationship is created | 
FollowDeletedEvent | Fired when a follow relationship is removed | 
FollowUpdatedEvent | Fired when follow settings are modified | 
| Bookmark Events | |
BookmarkAddedEvent | Fired when an activity is bookmarked | 
BookmarkDeletedEvent | Fired when a bookmark is removed | 
BookmarkUpdatedEvent | Fired when bookmark metadata is modified | 
| Connection Events | |
ConnectedEvent | Fired when successfully connected to WebSocket | 
ConnectionErrorEvent | Fired when connection fails or errors occur | 
HealthCheckEvent | Fired when health check is received |