Skip to content

Explore replacing Combine with async sequences #44

Description

@hisaac

EventMonitor uses Combine for everything: four NotificationCenter publishers plus a Defaults
publisher, all held in a Set<AnyCancellable>. Worth investigating whether the async equivalents are
a better fit now.

What the alternatives actually are

To answer the "not sure if it's AsyncStream or something else" — it is AsyncSequence/AsyncStream,
and after the dependency updates all three sources have one:

  • Notifications: NotificationCenter.notifications(named:) — an AsyncSequence.
  • Preferences: Defaults.updates(...) — confirmed present in Defaults 9.x.
  • Shortcuts: KeyboardShortcuts.events(for:) returns an AsyncStream<EventType> in 3.x, replacing
    the onKeyUp callback.

Depends on

The dependency updates. Two of those three APIs only exist in the newer majors, so this is a
follow-on rather than something to attempt first.

Worth weighing honestly

This is exploration, not a foregone conclusion. Points to actually decide on:

  • Cancellation. Set<AnyCancellable> cancels automatically on deallocation, which is tidy and
    hard to get wrong. The async version means owning Task handles and cancelling them yourself —
    more code, and a new way to leak.
  • Isolation. The async APIs compose more naturally with the main actor annotations the Swift 6
    work introduced, and the awkward hop currently needed for the Dock icon subscription would likely
    disappear.
  • It is four subscriptions. The Combine version is not complicated or buggy. "Newer" is not by
    itself a reason, and a rewrite is a chance to reintroduce bugs that are currently fixed.

A reasonable outcome of this issue is a written "no, and here is why".

Verify

Whatever the outcome, the behaviour must not regress: pointer centres on system events, respects the
monitoring preference, the shortcut works regardless of it, and the Dock icon toggle still applies.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions