recouse/eventsource
EventSource is a Swift package that provides a simple implementation of a client for [Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html) (SSE). It allows you to easily receive real-time updates from a server over a persistent HTTP connection, usin
Features
- [x] Simple Swift API for SSE
- [x] Supports data-only mode
- [x] Data race safety with Swift 6
Installation
The module name of the package is EventSource. Choose one of the instructions below to install and add the following import statement to your source code.
import EventSourceXcode Package Dependency
From Xcode menu: File > Swift Packages > Add Package Dependency
https://github.com/Recouse/EventSourceSwift Package Manager
In your Package.swift file, first add the following to the package dependencies:
.package(url: "https://github.com/Recouse/EventSource.git"),And then, include "EventSource" as a dependency for your target:
.target(name: "<target>", dependencies: [
.product(name: "EventSource", package: "EventSource"),
]),Usage
Using EventSource is easy. Simply create a new data task from an instance of EventSource with the URLRequest of the SSE endpoint you want to connect to, and await for events:
import EventSource
let task = Task {
let eventSource = EventSource()
let dataTask = eventSource.dataTask(for: urlRequest)
for await event in dataTask.events() {
switch event {
case .open:
print("Connection was opened.")
case .error(let error):
print("Received an error:", error.localizedDescription)
case .event(let event):
print("Received an event", event.data ?? "")
case .closed:
print("Connection was closed.")
}
}
}Use task.cancel() to explicitly close the connection. However, in that case .closed event won't be emitted.
Data-only mode
EventSource can be used in data-only mode, making it suitable for popular APIs like OpenAI. Below is an example using OpenAI's completions API:
Task {
var urlRequest = URLRequest(url: URL(string: "https://api.openai.com/v1/chat/completions")!)
urlRequest.allHTTPHeaderFields = [
"Content-Type": "application/json",
"Authorization": "Bearer \(accessToken)"
]
urlRequest.httpMethod = "POST"
urlRequest.httpBody = """
{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Why is the sky blue?"}
],
"stream": true
}
""".data(using: .utf8)!
let eventSource = EventSource(mode: .dataOnly)
let dataTask = eventSource.dataTask(for: urlRequest)
var response: String = ""
for await event in dataTask.events() {
switch event {
case .event(let event):
if let data = eventDevent.data?.data(using: .utf8) {
let chunk = try? JSONDecoder().decode(ChatCompletionChunk.self, from: data)
let string = chunk?.choices.first?.delta.content ?? ""
response += string
}
default:
break
}
}
print(response)
}Compatibility
- macOS 10.15+
- iOS 13.0+
- tvOS 13.0+
- watchOS 6.0+
- visionOS 1.0+
Dependencies
No dependencies.
Contributing
Contributions to are always welcomed! For more details see CONTRIBUTING.md.
Credits
- Mutex backport from swift-sharing
License
EventSource is released under the MIT License. See LICENSE for more information.
Package Metadata
Repository: recouse/eventsource
Default branch: main
README: README.md