### Complete Usage Example Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt A comprehensive example demonstrating how to integrate LDSwiftEventSource, including JSON parsing, reconnection logic, and graceful shutdown. ```APIDOC ## Complete Usage Example Full example demonstrating real-world SSE integration with JSON parsing, reconnection handling, and graceful shutdown. ```swift import LDSwiftEventSource import Foundation // MARK: - Data Models struct StreamMessage: Codable { let id: String let type: String let payload: [String: String] let timestamp: Date } // MARK: - Event Handler class ApplicationEventHandler: EventHandler { private var reconnectCount = 0 private let maxReconnects = 10 weak var delegate: StreamDelegate? func onOpened() { reconnectCount = 0 print("[SSE] Connected to event stream") delegate?.streamDidConnect() } func onClosed() { reconnectCount += 1 print("[SSE] Disconnected (attempt \(reconnectCount)/\(maxReconnects))") delegate?.streamDidDisconnect(willRetry: reconnectCount < maxReconnects) } func onMessage(eventType: String, messageEvent: MessageEvent) { guard let data = messageEvent.data.data(using: .utf8) else { return } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 do { let message = try decoder.decode(StreamMessage.self, from: data) delegate?.streamDidReceive(message: message, eventType: eventType) } catch { print("[SSE] Failed to decode message: \(error)") } } func onComment(comment: String) { // Server heartbeat print("[SSE] Heartbeat: \(comment)") } func onError(error: Error) { delegate?.streamDidEncounterError(error) } } // MARK: - Delegate Protocol protocol StreamDelegate: AnyObject { func streamDidConnect() func streamDidDisconnect(willRetry: Bool) func streamDidReceive(message: StreamMessage, eventType: String) func streamDidEncounterError(_ error: Error) } // MARK: - Stream Manager class EventStreamManager { private var eventSource: EventSource? private let handler = ApplicationEventHandler() func connect(to url: URL, token: String) { var config = EventSource.Config(handler: handler, url: url) config.headers = ["Authorization": "Bearer \(token)"] config.reconnectTime = 1.0 config.maxReconnectTime = 30.0 config.idleTimeout = 300.0 config.connectionErrorHandler = { error in if let httpError = error as? UnsuccessfulResponseError { // Don't retry on auth errors if [401, 403].contains(httpError.responseCode) { return .shutdown } } return .proceed } eventSource = EventSource(config: config) eventSource?.start() } func disconnect() { eventSource?.stop() eventSource = nil } func getLastEventId() -> String? { return eventSource?.getLastEventId() } } // MARK: - Usage let manager = EventStreamManager() let url = URL(string: "https://api.example.com/v1/events")! manager.connect(to: url, token: "your-auth-token") // To gracefully shutdown: // manager.disconnect() ``` ``` -------------------------------- ### EventSource Client Usage Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Demonstrates how to initialize, start, and stop the EventSource client, along with handling incoming SSE events. ```APIDOC ## EventSource Client Usage ### Description This section details the basic usage of the `EventSource` client for establishing and managing Server-Sent Events (SSE) connections. ### Method N/A (Client-side implementation) ### Endpoint N/A (Client-side implementation, requires a server endpoint URL) ### Parameters N/A (Configuration is handled via `EventSource.Config`) ### Request Example ```swift import LDSwiftEventSource // Create an event handler to receive SSE events class MyEventHandler: EventHandler { func onOpened() { print("Connection opened") } func onClosed() { print("Connection closed") } func onMessage(eventType: String, messageEvent: MessageEvent) { print("Received event: \(eventType)") print("Data: \(messageEvent.data)") print("Last Event ID: \(messageEvent.lastEventId)") } func onComment(comment: String) { print("Comment: \(comment)") } func onError(error: Error) { print("Error: \(error.localizedDescription)") } } // Initialize and start the EventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! let config = EventSource.Config(handler: handler, url: url) let eventSource = EventSource(config: config) eventSource.start() // Later, to stop the connection: eventSource.stop() // Check the last received event ID if let lastId = eventSource.getLastEventId() { print("Last event ID: \(lastId)") } ``` ### Response N/A (Event handling is done via the `EventHandler` protocol callbacks.) #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Basic EventSource Client Implementation in Swift Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Demonstrates how to create and manage an EventSource client in Swift. It includes setting up an event handler to process incoming SSE events (opened, closed, message, comment, error), initializing the EventSource with a URL and handler, starting the connection, and stopping it. It also shows how to retrieve the last received event ID. ```swift import LDSwiftEventSource // Create an event handler to receive SSE events class MyEventHandler: EventHandler { func onOpened() { print("Connection opened") } func onClosed() { print("Connection closed") } func onMessage(eventType: String, messageEvent: MessageEvent) { print("Received event: \(eventType)") print("Data: \(messageEvent.data)") print("Last Event ID: \(messageEvent.lastEventId)") } func onComment(comment: String) { print("Comment: \(comment)") } func onError(error: Error) { print("Error: \(error.localizedDescription)") } } // Initialize and start the EventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! let config = EventSource.Config(handler: handler, url: url) let eventSource = EventSource(config: config) eventSource.start() // Later, to stop the connection: eventSource.stop() // Check the last received event ID if let lastId = eventSource.getLastEventId() { print("Last event ID: \(lastId)") } ``` -------------------------------- ### Install LDSwiftEventSource with Carthage Source: https://github.com/launchdarkly/swift-eventsource/blob/main/README.md This snippet shows how to declare LDSwiftEventSource as a dependency in your Cartfile for use with the Carthage dependency manager. ```ogdl github "LaunchDarkly/swift-eventsource" ~> 3.3 ``` -------------------------------- ### Install LDSwiftEventSource with CocoaPods Source: https://github.com/launchdarkly/swift-eventsource/blob/main/README.md Instructions for integrating the LDSwiftEventSource library into an Xcode project using the CocoaPods dependency manager. Specify the pod name and version in your Podfile. ```ruby pod 'LDSwiftEventSource', '~> 3.3' ``` -------------------------------- ### Customizing EventSource Configuration in Swift Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Shows how to configure the EventSource client with custom settings. This includes changing the HTTP method (e.g., to 'REPORT'), providing a request body, adding custom HTTP headers, setting the initial last-event-id, configuring reconnection timing (initial, maximum, and backoff reset threshold), and setting an idle timeout. The example demonstrates creating an EventSource.Config object and passing it to the EventSource initializer. ```swift import LDSwiftEventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) // Use POST instead of GET config.method = "REPORT" // Add request body for POST/REPORT requests config.body = """ { "subscription": "updates", "filters": ["user", "system"] } """.data(using: .utf8) // Add custom HTTP headers config.headers = [ "Authorization": "Bearer your-token-here", "X-Custom-Header": "custom-value" ] // Set initial last-event-id for resuming streams config.lastEventId = "event-12345" // Configure reconnection timing (in seconds) config.reconnectTime = 1.0 // Initial reconnect delay config.maxReconnectTime = 30.0 // Maximum reconnect delay config.backoffResetThreshold = 60.0 // Time before backoff resets // Set idle timeout (connection timeout without data) config.idleTimeout = 300.0 // Create EventSource with custom configuration let eventSource = EventSource(config: config) eventSource.start() ``` -------------------------------- ### Complete SSE Integration with JSON Parsing and Reconnection Handling in Swift Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt This Swift code demonstrates a comprehensive example of integrating Server-Sent Events (SSE) using the LDSwiftEventSource library. It includes defining data models for stream messages, implementing an `EventHandler` to manage connection events and message processing (including JSON decoding), and a `StreamDelegate` protocol for communication. The `EventStreamManager` class handles the configuration and lifecycle of the `EventSource`, including setting headers, reconnection intervals, and custom error handling for specific HTTP error codes. The example also shows how to initiate the connection and disconnect gracefully. ```swift import LDSwiftEventSource import Foundation // MARK: - Data Models struct StreamMessage: Codable { let id: String let type: String let payload: [String: String] let timestamp: Date } // MARK: - Event Handler class ApplicationEventHandler: EventHandler { private var reconnectCount = 0 private let maxReconnects = 10 weak var delegate: StreamDelegate? func onOpened() { reconnectCount = 0 print("[SSE] Connected to event stream") delegate?.streamDidConnect() } func onClosed() { reconnectCount += 1 print("[SSE] Disconnected (attempt \(reconnectCount)/\(maxReconnects))") delegate?.streamDidDisconnect(willRetry: reconnectCount < maxReconnects) } func onMessage(eventType: String, messageEvent: MessageEvent) { guard let data = messageEvent.data.data(using: .utf8) else { return } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 do { let message = try decoder.decode(StreamMessage.self, from: data) delegate?.streamDidReceive(message: message, eventType: eventType) } catch { print("[SSE] Failed to decode message: \(error)") } } func onComment(comment: String) { // Server heartbeat print("[SSE] Heartbeat: \(comment)") } func onError(error: Error) { delegate?.streamDidEncounterError(error) } } // MARK: - Delegate Protocol protocol StreamDelegate: AnyObject { func streamDidConnect() func streamDidDisconnect(willRetry: Bool) func streamDidReceive(message: StreamMessage, eventType: String) func streamDidEncounterError(_ error: Error) } // MARK: - Stream Manager class EventStreamManager { private var eventSource: EventSource? = nil private let handler = ApplicationEventHandler() func connect(to url: URL, token: String) { var config = EventSource.Config(handler: handler, url: url) config.headers = ["Authorization": "Bearer \(token)"] config.reconnectTime = 1.0 config.maxReconnectTime = 30.0 config.idleTimeout = 300.0 config.connectionErrorHandler = { error in if let httpError = error as? UnsuccessfulResponseError { // Don't retry on auth errors if [401, 403].contains(httpError.responseCode) { return .shutdown } } return .proceed } eventSource = EventSource(config: config) eventSource?.start() } func disconnect() { eventSource?.stop() eventSource = nil } func getLastEventId() -> String? { return eventSource?.getLastEventId() } } // MARK: - Usage let manager = EventStreamManager() let url = URL(string: "https://api.example.com/v1/events")! manager.connect(to: url, token: "your-auth-token") // To gracefully shutdown: // manager.disconnect() ``` -------------------------------- ### Install LDSwiftEventSource with Swift Package Manager Source: https://github.com/launchdarkly/swift-eventsource/blob/main/README.md This code snippet demonstrates how to add LDSwiftEventSource as a dependency to your Swift package. It specifies the repository URL and the desired version constraint. ```swift dependencies: [ .package(url: "https://github.com/LaunchDarkly/swift-eventsource.git", .upToNextMajor(from: "3.3.0")) ] ``` -------------------------------- ### Dynamic Header Modification with HeaderTransform in Swift Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Illustrates how to use the `headerTransform` closure in EventSource.Config to dynamically modify HTTP headers for each connection attempt. This is particularly useful for refreshing authentication tokens. The example defines a TokenManager to simulate token refreshing and then assigns a closure to `config.headerTransform` that adds or updates the 'Authorization' header with the current token and can also remove headers. ```swift import LDSwiftEventSource class TokenManager { var currentToken: String = "initial-token" func refreshToken() { // Refresh token logic currentToken = "refreshed-token-\(Date().timeIntervalSince1970)" } } let tokenManager = TokenManager() let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) // Set base headers config.headers = ["X-Client-ID": "my-app"] // Transform headers on each connection/reconnection config.headerTransform = { existingHeaders in var headers = existingHeaders // Add or update the authorization header with fresh token headers["Authorization"] = "Bearer \(tokenManager.currentToken)" // Remove headers if needed headers.removeValue(forKey: "X-Debug") return headers } let eventSource = EventSource(config: config) eventSource.start() ``` -------------------------------- ### Build and Test with SwiftPM Source: https://github.com/launchdarkly/swift-eventsource/blob/main/CONTRIBUTING.md Instructions for building and running tests for the LDSwiftEventSource library using the Swift Package Manager. This is a common method for Swift projects. ```bash swift test ``` -------------------------------- ### Monitoring EventSource ReadyState Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Illustrates how to monitor connection lifecycle states by implementing the EventHandler protocol and reacting to state transitions via NotificationCenter. ```swift import LDSwiftEventSource class StateAwareHandler: EventHandler { enum AppConnectionState { case disconnected, connecting, connected } var connectionState: AppConnectionState = .disconnected func onOpened() { connectionState = .connected NotificationCenter.default.post(name: .connectionStateChanged, object: connectionState) } func onClosed() { connectionState = .connecting NotificationCenter.default.post(name: .connectionStateChanged, object: connectionState) } func onMessage(eventType: String, messageEvent: MessageEvent) { } func onComment(comment: String) { } func onError(error: Error) { } } extension Notification.Name { static let connectionStateChanged = Notification.Name("connectionStateChanged") } ``` -------------------------------- ### Run Contract Tests Source: https://github.com/launchdarkly/swift-eventsource/blob/main/CONTRIBUTING.md Command to execute the standardized contract tests for LaunchDarkly SSE client implementations. This ensures compatibility across different SDKs. ```bash make contract-tests ``` -------------------------------- ### Generate API Documentation with Jazzy Source: https://github.com/launchdarkly/swift-eventsource/blob/main/CONTRIBUTING.md Command to generate API documentation for the LDSwiftEventSource library using Jazzy. This process is configured separately and aims for 100% documentation coverage. ```bash jazzy ``` -------------------------------- ### EventSource.Config Customization Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Explains how to configure the EventSource client with custom settings like HTTP method, headers, and reconnection logic. ```APIDOC ## EventSource.Config Customization ### Description This section details the `EventSource.Config` struct, which allows for detailed customization of the EventSource client's behavior, including HTTP method, request body, headers, and reconnection parameters. ### Method N/A (Client-side configuration) ### Endpoint N/A (Client-side configuration, requires a server endpoint URL) ### Parameters N/A (Configuration is handled via `EventSource.Config` properties) ### Request Example ```swift import LDSwiftEventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) // Use POST instead of GET config.method = "REPORT" // Add request body for POST/REPORT requests config.body = """{ \"subscription\": \"updates\", \"filters\": [\"user\", \"system\"] }""" .data(using: .utf8) // Add custom HTTP headers config.headers = [ "Authorization": "Bearer your-token-here", "X-Custom-Header": "custom-value" ] // Set initial last-event-id for resuming streams config.lastEventId = "event-12345" // Configure reconnection timing (in seconds) config.reconnectTime = 1.0 // Initial reconnect delay config.maxReconnectTime = 30.0 // Maximum reconnect delay config.backoffResetThreshold = 60.0 // Time before backoff resets // Set idle timeout (connection timeout without data) config.idleTimeout = 300.0 // Create EventSource with custom configuration let eventSource = EventSource(config: config) eventSource.start() ``` ### Response N/A (Configuration affects client behavior, not direct response structure.) #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Implement EventHandler Protocol for SSE Streams Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Provides a template for implementing the EventHandler protocol to process connection lifecycle events, incoming messages, comments, and errors. It shows how to handle different event types and extract data from the stream. ```swift import LDSwiftEventSource class StreamEventHandler: EventHandler { func onOpened() { print("SSE connection established") } func onClosed() { print("SSE connection closed") } func onMessage(eventType: String, messageEvent: MessageEvent) { switch eventType { case "message": print("Default message: \(messageEvent.data)") case "update": print("Update received") default: print("Unknown event type") } } func onComment(comment: String) { print("Server comment: \(comment)") } func onError(error: Error) { print("Error: \(error.localizedDescription)") } } let handler = StreamEventHandler() let config = EventSource.Config(handler: handler, url: URL(string: "https://api.example.com/stream")!) let eventSource = EventSource(config: config) eventSource.start() ``` -------------------------------- ### Configure Connection Error Handling in LDSwiftEventSource Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Demonstrates how to define a custom connectionErrorHandler to decide whether to shutdown or reconnect based on HTTP status codes or network errors. This allows for granular control over client behavior during stream interruptions. ```swift import LDSwiftEventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) config.connectionErrorHandler = { error in if let responseError = error as? UnsuccessfulResponseError { let statusCode = responseError.responseCode if statusCode == 401 || statusCode == 403 { return .shutdown } if statusCode == 204 { return .shutdown } if (400..<500).contains(statusCode) && statusCode != 408 { return .shutdown } } return .proceed } let eventSource = EventSource(config: config) eventSource.start() ``` -------------------------------- ### Configure URLSession for EventSource Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Shows how to customize the underlying URLSessionConfiguration for an EventSource instance. This includes modifying cellular access, timeout intervals, and proxy settings. ```swift import LDSwiftEventSource let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) var sessionConfig = config.urlSessionConfiguration sessionConfig.allowsCellularAccess = false sessionConfig.sessionSendsLaunchEvents = true sessionConfig.isDiscretionary = false sessionConfig.timeoutIntervalForResource = 600 sessionConfig.connectionProxyDictionary = [ kCFNetworkProxiesHTTPEnable: true, kCFNetworkProxiesHTTPProxy: "proxy.example.com", kCFNetworkProxiesHTTPPort: 8080 ] config.urlSessionConfiguration = sessionConfig let eventSource = EventSource(config: config) eventSource.start() ``` -------------------------------- ### Handling SSE MessageEvents Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Demonstrates how to implement the EventHandler protocol to process incoming MessageEvent payloads, access event IDs for stream resumption, and utilize Equatable/Hashable conformance. ```swift import LDSwiftEventSource class DataHandler: EventHandler { func onOpened() { } func onClosed() { } func onComment(comment: String) { } func onError(error: Error) { } func onMessage(eventType: String, messageEvent: MessageEvent) { let data: String = messageEvent.data let lastId: String = messageEvent.lastEventId if let jsonData = data.data(using: .utf8) { do { let decoded = try JSONDecoder().decode(ServerUpdate.self, from: jsonData) processUpdate(decoded, eventId: lastId) } catch { print("Failed to decode: \(error)") } } let event1 = MessageEvent(data: "test", lastEventId: "123") let event2 = MessageEvent(data: "test", lastEventId: "123") print(event1 == event2) var eventSet: Set = [] eventSet.insert(messageEvent) } private func processUpdate(_ update: ServerUpdate, eventId: String) { } } struct ServerUpdate: Codable { let type: String let payload: String } ``` -------------------------------- ### ReadyState Enum Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Represents the possible states of an EventSource connection throughout its lifecycle. ```APIDOC ## ReadyState Enum representing the possible states of an EventSource connection throughout its lifecycle. ### Description The `ReadyState` enum defines the different connection statuses an `EventSource` can be in, from initial connection attempts to a permanently closed state. ### States - **.raw**: EventSource has not been started yet. - **.connecting**: Attempting to establish a connection. - **.open**: Connected and actively receiving events. - **.closed**: Connection is closed, but the EventSource will attempt to reconnect. - **.shutdown**: Permanently closed; no further reconnection attempts will be made. ### State Transitions The state transitions are managed internally by the `EventSource` class: `raw -> connecting -> open -> closed -> connecting -> open ...` Transitions to `.shutdown` can occur via calling `stop()` or through error handling. ### Example Usage Monitoring connection state through `EventHandler`: ```swift import LDSwiftEventSource // ReadyState values: (as described above) // Example: Monitoring connection state through EventHandler class StateAwareHandler: EventHandler { enum AppConnectionState { case disconnected, connecting, connected } var connectionState: AppConnectionState = .disconnected func onOpened() { // Transition to .open state occurred connectionState = .connected NotificationCenter.default.post(name: .connectionStateChanged, object: connectionState) } func onClosed() { // Transition to .closed state, will auto-reconnect connectionState = .connecting NotificationCenter.default.post(name: .connectionStateChanged, object: connectionState) } func onMessage(eventType: String, messageEvent: MessageEvent) { // Connection is in .open state } func onComment(comment: String) { } func onError(error: Error) { // May transition to .closed or .shutdown } } extension Notification.Name { static let connectionStateChanged = Notification.Name("connectionStateChanged") } ``` ``` -------------------------------- ### HeaderTransform for Dynamic Headers Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Illustrates how to use `HeaderTransform` to dynamically modify HTTP headers, such as refreshing authentication tokens. ```APIDOC ## HeaderTransform for Dynamic Headers ### Description This section explains the use of `HeaderTransform`, a function type that enables dynamic modification of HTTP headers for each connection attempt. This is particularly useful for scenarios like refreshing authentication tokens. ### Method N/A (Client-side configuration) ### Endpoint N/A (Client-side configuration, requires a server endpoint URL) ### Parameters N/A (Configuration is handled via `EventSource.Config.headerTransform`) ### Request Example ```swift import LDSwiftEventSource class TokenManager { var currentToken: String = "initial-token" func refreshToken() { // Refresh token logic currentToken = "refreshed-token-\(Date().timeIntervalSince1970)" } } let tokenManager = TokenManager() let handler = MyEventHandler() let url = URL(string: "https://api.example.com/events")! var config = EventSource.Config(handler: handler, url: url) // Set base headers config.headers = ["X-Client-ID": "my-app"] // Transform headers on each connection/reconnection config.headerTransform = { existingHeaders in var headers = existingHeaders // Add or update the authorization header with fresh token headers["Authorization"] = "Bearer \(tokenManager.currentToken)" // Remove headers if needed headers.removeValue(forKey: "X-Debug") return headers } let eventSource = EventSource(config: config) eventSource.start() ``` ### Response N/A (Header transformation affects outgoing requests, not direct responses.) #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Handle UnsuccessfulResponseError in Swift Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Demonstrates how to catch and handle UnsuccessfulResponseError to manage specific HTTP status codes like 401, 403, and 429. It also shows how to differentiate between server-side HTTP errors and client-side URLErrors. ```swift import LDSwiftEventSource class ErrorHandler: EventHandler { func onOpened() { } func onClosed() { } func onMessage(eventType: String, messageEvent: MessageEvent) { } func onComment(comment: String) { } func onError(error: Error) { if let unsuccessfulResponse = error as? UnsuccessfulResponseError { let statusCode = unsuccessfulResponse.responseCode switch statusCode { case 401: handleUnauthorized() case 403: handleForbidden() case 404: handleNotFound() case 429: handleRateLimited() case 500...599: handleServerError(statusCode) default: print("Unexpected HTTP error: \(statusCode)") } } else if let urlError = error as? URLError { switch urlError.code { case .notConnectedToInternet: handleNoConnection() case .timedOut: handleTimeout() default: print("URL error: \(urlError.localizedDescription)") } } else { print("Unknown error: \(error)") } } private func handleUnauthorized() { print("Token expired - refresh needed") } private func handleForbidden() { print("Access denied") } private func handleNotFound() { print("Stream endpoint not found") } private func handleRateLimited() { print("Rate limited - backing off") } private func handleServerError(_ code: Int) { print("Server error: \(code)") } private func handleNoConnection() { print("No internet connection") } private func handleTimeout() { print("Connection timed out") } } ``` -------------------------------- ### MessageEvent Struct Source: https://context7.com/launchdarkly/swift-eventsource/llms.txt Represents a received Server-Sent Event, including its data payload and the last event ID for stream resumption. ```APIDOC ## MessageEvent Struct representing a received SSE event containing the data payload and the last event ID for stream resumption. ### Description The `MessageEvent` struct is used within the `onMessage` callback of the `EventHandler` protocol. It provides access to the event's `data` and `lastEventId`. ### Usage ```swift import LDSwiftEventSource // MessageEvent is received in onMessage callback class DataHandler: EventHandler { func onOpened() { } func onClosed() { } func onComment(comment: String) { } func onError(error: Error) { } func onMessage(eventType: String, messageEvent: MessageEvent) { // Access the event data let data: String = messageEvent.data // Access the last event ID for resumption let lastId: String = messageEvent.lastEventId // Parse JSON data if let jsonData = data.data(using: .utf8) { do { let decoded = try JSONDecoder().decode(ServerUpdate.self, from: jsonData) processUpdate(decoded, eventId: lastId) } catch { print("Failed to decode: \(error)") } } // MessageEvent supports Equatable and Hashable let event1 = MessageEvent(data: "test", lastEventId: "123") let event2 = MessageEvent(data: "test", lastEventId: "123") print(event1 == event2) // true // Can be used in collections var eventSet: Set = [] eventSet.insert(messageEvent) } private func processUpdate(_ update: ServerUpdate, eventId: String) { // Process the update } } struct ServerUpdate: Codable { let type: String let payload: String } ``` ### Properties - **data** (String) - The data payload of the Server-Sent Event. - **lastEventId** (String) - The last event ID received, used for stream resumption. ```