{"id":24352600,"url":"https://github.com/flowduino/serialswift","last_synced_at":"2026-02-10T04:36:58.524Z","repository":{"id":63910103,"uuid":"526322431","full_name":"Flowduino/SerialSwift","owner":"Flowduino","description":"MacOS Serial solution (Observable \u0026 Event-Driven) to make integration of Serial peripherals trivial","archived":false,"fork":false,"pushed_at":"2022-09-03T20:04:04.000Z","size":15,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-01T11:42:12.480Z","etag":null,"topics":["event","event-driven","events","ios","mac","macos","observable","observer","observer-pattern","rs232","serial","swift","swift5","swift5-7","swiftui"],"latest_commit_sha":null,"homepage":"https://flowduino.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flowduino.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["Flowduino"]}},"created_at":"2022-08-18T18:06:54.000Z","updated_at":"2023-10-12T03:30:55.000Z","dependencies_parsed_at":"2022-11-29T07:12:19.294Z","dependency_job_id":null,"html_url":"https://github.com/Flowduino/SerialSwift","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowduino%2FSerialSwift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowduino%2FSerialSwift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowduino%2FSerialSwift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowduino%2FSerialSwift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flowduino","download_url":"https://codeload.github.com/Flowduino/SerialSwift/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243165501,"owners_count":20246722,"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":["event","event-driven","events","ios","mac","macos","observable","observer","observer-pattern","rs232","serial","swift","swift5","swift5-7","swiftui"],"created_at":"2025-01-18T15:55:11.999Z","updated_at":"2026-02-10T04:36:58.488Z","avatar_url":"https://github.com/Flowduino.png","language":"Swift","funding_links":["https://github.com/sponsors/Flowduino"],"categories":[],"sub_categories":[],"readme":"# SerialSwift\n\n\u003cp\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-5.1%2B-yellowgreen.svg?style=flat\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/macOS-10.15+-179AC8.svg\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg\" /\u003e\n    \u003ca href=\"https://github.com/apple/swift-package-manager\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=flat\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n`SerialSwift` makes communicating with your Serial Peripherals on MacOS trivial.\n\nBetter still, `SerialSwift` is designed to be fundamnetally *Observable* and *Event-Driven*, making it easier than ever before to consume information coming into your application from your external Serial peripheral(s).\n\n`SerialSwift` is built on top of a number of packages:\n- [`ThreadSafeSwift` from ourselves at Flowduino](https://github.com/Flowduino/ThreadSafeSwift) is used to ensure Thread-Safety throughout the library\n- [`Observable` from ourselves at Flowduino](https://github.com/Flowduino/Observable) is used to provide protocol-conformance Observer Pattern support throughout the library\n- [`EventDrivenSwift` from ourselves at Flowduino](https://github.com/Flowduino/EventDrivenSwift) is used to emit relevant and extremely high-performance *Events* for every Serial Event your Peripherals generate.\n- [`ORSSerialPort` from Armadsen](https://github.com/armadsen/ORSSerialPort) is used to actually interface with your Serial Peripherals.\n\nIn this way, `SerialSwift` can be integrated into your code in any way you prefer, making it extremely versatile.\n\n## Installation\n### Xcode Projects\nSelect `File` -\u003e `Swift Packages` -\u003e `Add Package Dependency` and enter `https://github.com/Flowduino/SerialSwift.git`\n\n### Swift Package Manager Projects\nYou can use `SerialSwift` as a Package Dependency in your own Packages' `Package.swift` file:\n```swift\nlet package = Package(\n    //...\n    dependencies: [\n        .package(\n            url: \"https://github.com/Flowduino/SerialSwift.git\",\n            .upToNextMajor(from: \"1.0.0\")\n        ),\n    ],\n    //...\n)\n```\n\nFrom there, refer to `SerialSwift` as a \"target dependency\" in any of _your_ package's targets that need it.\n\n```swift\ntargets: [\n    .target(\n        name: \"YourLibrary\",\n        dependencies: [\n          \"SerialSwift\",\n        ],\n        //...\n    ),\n    //...\n]\n```\nYou can then do `import SerialSwift` in any code that requires it.\n\n## Usage\n\nHere are some quick and easy usage examples for the features provided by `SerialSwift`:\n\n### Connecting to your Serial Peripheral\nYou can create an instance of `SerialSwift` per Peripheral as easily as this:\n```swift\nvar mySerialDevice = Serial[\"/dev/cu.myserialdevice\", .baud9600]\n```\nYou would, of course, substitute both parameters in the above example with (firstly) the path to your Serial device, followed by (secondly) the Baud Rate your Serial Device uses.\n\nIt is recommended that you retain a reference to your `Serialable` object somewhere globally in your application (such as on the `Environment` of your application, or as a *Singleton*). This is because, from the moment you connect to your Serial peripheral, it will begin emitting *Events* that you can consume anywhere in your application... as demonstrated below.\n\n### Events your Serial device will emit throughout your Application\nNow that you have connected to your Serial device, the following *Events* will be emitted universally throughout your application, and can be consumed from *anywhere* in your code.\n\n#### `SerialPortClosedEvent`\nIf you need to perform a specific operation any time your connection to your Serial device closes, you can do so simply from *anywhere* in your code:\n```swift\nSerialPortClosedEvent.addListener(self) { (event: SerialPortClosedEvent, priority) in\n    /**\n        Your code goes in here!\n        Properties available to you:\n        `event.refTime` = the precise \"Mach Time\" at which the Serial Port closed\n        `event.serial` = A reference to the Serial device which triggered the Event.\n        \n        You can use `if ObjectIdentifier(event.serial) != ObjectIdentifier(mySerialDevice) { return }` to ensure you're only acting on Events emitted by a specific Serial device \n    */\n}\n```\n\n#### `SerialPortDataReceivedEvent`\nIf you need to perform a specific operation any time your Serial device sends Data to your computer, you can do so simply from *anywhere* in your code:\n```swift\nSerialPortDataReceivedEvent.addListener(self) { (event: SerialPortDataReceivedEvent, priority) in\n    /**\n        Your code goes in here!\n        Properties available to you:\n        `event.refTime` = the precise \"Mach Time\" at which the Serial Port closed\n        `event.serial` = A reference to the Serial device which triggered the Event.\n        `event.data` = The actual `Data` your Serial device sent to your computer.\n        \n        You can use `if ObjectIdentifier(event.serial) != ObjectIdentifier(mySerialDevice) { return }` to ensure you're only acting on Events emitted by a specific Serial device \n    */\n}\n```\n\n#### `SerialPortErrorEvent`\nIf you need to perform a specific operation any time your Serial device encounters an Error, you can do so simply from *anywhere* in your code:\n```swift\nSerialPortErrorEvent.addListener(self) { (event: SerialPortErrorEvent, priority) in\n    /**\n        Your code goes in here!\n        Properties available to you:\n        `event.refTime` = the precise \"Mach Time\" at which the Serial Port closed\n        `event.serial` = A reference to the Serial device which triggered the Event.\n        `event.error` = The actual `Error` your Serial device encountered.\n        \n        You can use `if ObjectIdentifier(event.serial) != ObjectIdentifier(mySerialDevice) { return }` to ensure you're only acting on Events emitted by a specific Serial device \n    */\n}\n```\n\n#### `SerialPortOpenedEvent`\nIf you need to perform a specific operation any time your Serial device establishes a connection with your Computer, you can do so simply from *anywhere* in your code:\n```swift\nSerialPortOpenedEvent.addListener(self) { (event: SerialPortOpenedEvent, priority) in\n    /**\n        Your code goes in here!\n        Properties available to you:\n        `event.refTime` = the precise \"Mach Time\" at which the Serial Port closed\n        `event.serial` = A reference to the Serial device which triggered the Event.\n        \n        You can use `if ObjectIdentifier(event.serial) != ObjectIdentifier(mySerialDevice) { return }` to ensure you're only acting on Events emitted by a specific Serial device \n    */\n}\n```\n\n#### `SerialPortRemovedEvent`\nIf you need to perform a specific operation any time your Serial device disconnects from your Computer, you can do so simply from *anywhere* in your code:\n```swift\nSerialPortRemovedEvent.addListener(self) { (event: SerialPortRemovedEvent, priority) in\n    /**\n        Your code goes in here!\n        Properties available to you:\n        `event.refTime` = the precise \"Mach Time\" at which the Serial Port closed\n        `event.serial` = A reference to the Serial device which triggered the Event.\n        \n        You can use `if ObjectIdentifier(event.serial) != ObjectIdentifier(mySerialDevice) { return }` to ensure you're only acting on Events emitted by a specific Serial device \n    */\n}\n```\n\n## License\n\n`SerialSwift` is available under the MIT license. See the [LICENSE file](./LICENSE) for more info.\n\n## Join us on Discord\n\nIf you require additional support, or would like to discuss `SerialSwift`, Swift, or any other topics related to Flowduino, you can [join us on Discord](https://discord.com/invite/GdZZKFTQ2A).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowduino%2Fserialswift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowduino%2Fserialswift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowduino%2Fserialswift/lists"}