Skip to content

Instantly share code, notes, and snippets.

@GregoryMaks
Created August 1, 2023 10:32
Show Gist options
  • Save GregoryMaks/cb720d484f7ff8313ab9911a851e15fb to your computer and use it in GitHub Desktop.
Save GregoryMaks/cb720d484f7ff8313ab9911a851e15fb to your computer and use it in GitHub Desktop.
Observes current running applications through `NSWorkspace` and notifies if any of the requested applications change their running status
import AppKit
import Combine
import CombineExt
import Foundation
import SharedUtils
// sourcery: Automockable
protocol RunningApplicationsObserverType {
func observeApplicationsRunningStatus(bundleIdentifiers: [String]) -> AnyPublisher<Void, Never>
}
///
/// Observes current running applications through `NSWorkspace` and notifies if any of the requested applications change their running
/// status
///
public class RunningApplicationsObserver: RunningApplicationsObserverType {
let workspace: Workspace
init(workspace: Workspace = WorkspaceManagement()) {
self.workspace = workspace
}
// MARK: - RunningApplicationsObserverType
func observeApplicationsRunningStatus(bundleIdentifiers: [String]) -> AnyPublisher<Void, Never> {
AnyPublisher.create { subscriber in
var disposeBag = Set<AnyCancellable>()
let publishers = self.triggerNotifications.map { self.workspace.notificationCenter.publisher(for: $0) }
Publishers.MergeMany(publishers)
.filter { notification in
guard let application = notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication,
let bundleIdentifier = application.bundleIdentifier,
bundleIdentifiers.contains(bundleIdentifier)
else {
return false
}
return true
}
.receive(on: DispatchQueue.main)
.sink { _ in
subscriber.send(())
}
.store(in: &disposeBag)
return AnyCancellable {
disposeBag.removeAll()
}
}
}
private let triggerNotifications: [NSNotification.Name] = [
NSWorkspace.didLaunchApplicationNotification,
NSWorkspace.didTerminateApplicationNotification
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment