{"id":13904914,"url":"https://github.com/inaka/EventSource","last_synced_at":"2025-07-18T02:32:16.429Z","repository":{"id":27739220,"uuid":"31226963","full_name":"inaka/EventSource","owner":"inaka","description":"A simple Swift client library for the Server Sent Events (SSE)","archived":false,"fork":false,"pushed_at":"2022-05-27T05:33:33.000Z","size":9051,"stargazers_count":460,"open_issues_count":23,"forks_count":127,"subscribers_count":46,"default_branch":"master","last_synced_at":"2024-04-24T14:20:18.784Z","etag":null,"topics":["eventsource","sse","sse-client","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inaka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-23T20:05:11.000Z","updated_at":"2024-04-23T14:17:03.000Z","dependencies_parsed_at":"2022-07-14T01:20:33.301Z","dependency_job_id":null,"html_url":"https://github.com/inaka/EventSource","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2FEventSource","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2FEventSource/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2FEventSource/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2FEventSource/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inaka","download_url":"https://codeload.github.com/inaka/EventSource/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226336404,"owners_count":17608828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eventsource","sse","sse-client","swift"],"created_at":"2024-08-06T23:01:06.400Z","updated_at":"2024-11-25T13:30:42.559Z","avatar_url":"https://github.com/inaka.png","language":"Swift","funding_links":[],"categories":["HarmonyOS","Swift"],"sub_categories":["Windows Manager"],"readme":"![EventSource](header.png)\n\n## EventSource\nSSE Client written on Swift using NSURLSession.\n\n[![Build Status](https://api.travis-ci.org/inaka/EventSource.svg)](https://travis-ci.org/inaka/EventSource) [![codecov.io](https://codecov.io/github/inaka/EventSource/badge.svg?branch=master)](https://codecov.io/github/inaka/EventSource?branch=master) [![codecov.io](https://img.shields.io/badge/pod-v3.0.1-brightgreen.svg)](https://github.com/inaka/EventSource/blob/master/IKEventSource.podspec)\n\n### Abstract\n\nThis is an EventSource implementation written on Swift following the [W3C EventSource](http://www.w3.org/TR/eventsource/) document. If something is missing or not completely right open an issue and I'll work on it! \n\nIf you like the library please leave us a ★. That helps us to stay engaged on the mantainence!\n\n### Changes from version 2.2.1 to 3.0\n\nI took some time to review all the forks, pull requests and issues opened on github. The main changes and complains I found were related to the connection and the `Last-Event-Id` handling.\n\nThe changes on this version are:\n\n- `EventSource` doesn't connect automatically anymore. It waits until  `connect(lastEventId: String? = nil)` method is called. This method accepts a `lastEventId` which will be sent to the server upon connection.\n- `EventSource` lets you call `disconnect()` whenever you want.\n- `EventSource` doesn't store the `Last-Event-Id` anymore and you will have to take care of storing the `id` and sending using it or not in the `connect` method.\n- `EventSource` doesn't reconnect at all. If a network layer error occurs (disconnection, timeout, etc) or if the server closes the connection you will have to take care to reconnect with the server.\n- Modularization. This library has been around since `Swift 1.0` and started just as a way to learn the language. With this new version the whole code has been improved, commented and fully tested to make it easier to track problems and extend in the future.\n\n### How to use it?\n\nThere is a simple working sample in the repository. Check the ViewController.swift to see how to use it.\n\nAlso in `sse-server` folder you will find an extremely simple `node.js` server to test the library. To run the server you just need to:\n\n- `npm install`\n- `node sse.js`\n\n### Install\n\n#### Cocoapods\n\n1) Include EventSource in your `Podfile`: `pod 'IKEventSource'`\n\n2) Import the framework:\n\n```\nimport IKEventSource\n```\n\n#### Carthage\n\n1) Include EventSource in your `Cartfile`: `github \"inaka/EventSource\"`\n\n2) Import the framework:\n\n```\nimport IKEventSource\n```\n\nFor further reference see [Carthage's documentation](https://github.com/Carthage/Carthage/blob/master/README.md).\n\n#### Swift Package Manager\n\n1) Include EventSource in your `Package.swift`: `github \"inaka/EventSource\"`\n```swift\nimport PackageDescription\n\nlet package = Package(\ndependencies: [\n    .package(url: \"https://github.com/inaka/EventSource.git\", .branch(\"master\"))\n])\n```\n\n2) Import the framework:\n\n```\nimport IKEventSource\n```\n\n#### Swift API:\n\n```swift\n/// RetryTime: This can be changed remotly if the server sends an event `retry:`\nvar retryTime: Int { get }\n\n/// URL where EventSource will listen for events.\nvar url: URL { get }\n\n/// The last event id received from server. This id is neccesary to keep track of the last event-id received to avoid\n/// receiving duplicate events after a reconnection.\nvar lastEventId: String? { get }\n\n/// Current state of EventSource\nvar readyState: EventSourceState { get }\n\n/// Method used to connect to server. It can receive an optional lastEventId indicating the Last-Event-ID\n///\n/// - Parameter lastEventId: optional value that is going to be added on the request header to server.\nfunc connect(lastEventId: String?)\n\n/// Method used to disconnect from server.\nfunc disconnect()\n\n/// Returns the list of event names that we are currently listening for.\n///\n/// - Returns: List of event names.\nfunc events() -\u003e [String]\n\n/// Callback called when EventSource has successfully connected to the server.\n///\n/// - Parameter onOpenCallback: callback\nfunc onOpen(_ onOpenCallback: @escaping (() -\u003e Void))\n\n/// Callback called once EventSource has disconnected from server. This can happen for multiple reasons.\n/// The server could have requested the disconnection or maybe a network layer error, wrong URL or any other\n/// error. The callback receives as parameters the status code of the disconnection, if we should reconnect or not\n/// following event source rules and finally the network layer error if any. All this information is more than\n/// enought for you to take a decition if you should reconnect or not.\n/// - Parameter onOpenCallback: callback\nfunc onComplete(_ onComplete: @escaping ((Int?, Bool?, NSError?) -\u003e Void))\n\n/// This callback is called everytime an event with name \"message\" or no name is received.\nfunc onMessage(_ onMessageCallback: @escaping ((_ id: String?, _ event: String?, _ data: String?) -\u003e Void))\n\n/// Add an event handler for an specific event name.\n///\n/// - Parameters:\n///   - event: name of the event to receive\n///   - handler: this handler will be called everytime an event is received with this event-name\nfunc addEventListener(_ event: String,\n                      handler: @escaping ((_ id: String?, _ event: String?, _ data: String?) -\u003e Void))\n\n/// Remove an event handler for the event-name\n///\n/// - Parameter event: name of the listener to be remove from event source.\nfunc removeEventListener(_ event: String)\n\n\n```\n\n\n#### Examples:\n---\n**Event**:\n\n```\nid: event-id\nevent: event-name\ndata: event-data\n```\n\n**Calls** \n\n```\neventSource.addEventListener(\"event-name\") { (id, event, data) in\n  // Here you get an event 'event-name'\n}\n```\n---\n\n**Event**:\n\n```\nid: event-id\ndata: event-data\n```\n\n```\ndata: event-data\n```\n\n**Calls** \n\n```\neventSource.onMessage { (id, event, data) in\n  // Here you get an event without event name!\n}\n```\n---\n\n**Event**:\n\n```\nid: event-id\ndata: event-data-1\ndata: event-data-2\ndata: event-data-3\n```\n\n**Calls** \n\n```\neventSource.onMessage { (id, event, data) in\n  // Here you get an event without event name!\n  // data: event-data-1\\nevent-data-2\\nevent-data-3\n}\n```\n---\n\n**Event**:\n\n```\n:heartbeat\n```\n\n**Calls** \n\n```\nnothing it's a comment\n```\n---\n\n### Live example\n\nThis is the example shipped with the app. If you run the server and run the app you will be able to see this example live. The moving box is just to show that everything works on background and the main thread performance shows no degradation. (The gif is pretty bad to see that, but if you click on the image you will be taken to the gfycat version of the gif which runs way smoother) \n\n![Sample](sample.gif)\n\n### Contributors\nThanks to all the contributors for pointing out missing stuff or problems and fixing them or opening issues!!\n\n- [hleinone](https://github.com/hleinone)\n- [chrux](https://github.com/chrux)\n- [danielsht86](https://github.com/danielsht86)\n- [Zeeker](https://github.com/Zeeker)\n- [col](https://github.com/col)\n- [heyzooi](https://github.com/heyzooi)\n- [alexpalman](https://github.com/alexpalman)\n- [robbiet480](https://github.com/robbiet480)\n- [tbaranes](https://github.com/tbaranes)\n- [jwfriese](https://github.com/jwfriese)\n\n### Contact Us\nIf you find any **bugs** or have a **problem** while using this library, please [open an issue](https://github.com/inaka/EventSource/issues/new) in this repo (or a pull request :)).\n\nPlease provide an example of the problem you are facing. If an event is not correctly parsed please provide a sample event.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2FEventSource","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finaka%2FEventSource","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2FEventSource/lists"}