- Notifications
You must be signed in to change notification settings - Fork0
Easily monitor async sequences using Swift concurrency
License
samsonjs/AsyncMonitor
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
AsyncMonitor is a Swift library that provides a simple and easy-to-use way to manage Swift concurrencyTasks that observe async sequences. TheAsyncMonitor class allows you to create tasks that observe streams and call the given closure with each new value, and optionally also with a context parameter so you don't have to manage its lifetime.
It uses a SwiftTask to ensure that all resources are properly cleaned up when theAsyncMonitor is cancelled or deallocated.
That's it. It's pretty trivial. I just got tired of writing it over and over, mainly for notifications. You still have to map yourNotifications to something sendable, which brings me to another point. This package pairs nicely withNotificationSmuggler for a complete notification handling system in the Swift 6 concurrency world.
The simplest example uses a closure that receives the notification. The closure is async so you can await in there if you need to.
import AsyncMonitorclassSimplestVersion{letcancellable=NotificationCenter.default.notifications(named:.NSCalendarDayChanged).map(\.name).monitor{ _inprint("The date is now\(Date.now)")}}
This example uses the context parameter to avoid reference cycles withself.
finalclassWithContext:Sendable{nonisolated(unsafe)var cancellables=Set<AnyAsyncCancellable>()init(){NotificationCenter.default.notifications(named:.NSCalendarDayChanged).map(\.name).monitor(context:self){ _self, _in _self.dayChanged()}.store(in:&cancellables)}func dayChanged(){print("The date is now\(Date.now)")}}
Working with Combine publishers is trivial thanks toAnyPublisher.values.
@preconcurrencyimport CombineclassCombineExample{varcancellables:Set<AnyAsyncCancellable>=[]init(){Timer.publish(every:1.0, on:.main, in:.common).autoconnect().values.monitor{ dateinprint("Timer fired at\(date)")}.store(in:&cancellables)}}
When you need to observe an object that usesKVO there's an extension method you can use to monitor it:
classKVOExample{varcancellables:Set<AnyAsyncCancellable>=[]init(){letprogress=Progress(totalUnitCount:42) progress.monitorValues(for: \.fractionCompleted, options:[.initial,.new]){ fractioninprint("Progress is\(fraction.formatted(.percent))%")}.store(in:&cancellables)}}
The only way to install this package is with Swift Package Manager (SPM). Pleasefile a new issue or submit a pull-request if you want to use something else.
This package is supported on iOS 17.0+ and macOS 14.0+.
When you're integrating this into an app with Xcode then go to your project's Package Dependencies and enter the URLhttps://github.com/samsonjs/AsyncMonitor and then go through the usual flow for adding packages.
When you're integrating this using SPM on its own then add this to the list of dependencies your Package.swift file:
.package(url:"https://github.com/samsonjs/AsyncMonitor.git",.upToNextMajor(from:"0.3.1"))
and then add"AsyncMonitor" to the list of dependencies in your target as well.
Copyright © 2025Sami Samhurisami@samhuri.net. Released under the terms of theMIT License.
About
Easily monitor async sequences using Swift concurrency
Resources
License
Uh oh!
There was an error while loading.Please reload this page.