I have a GlobalActor
with some methods on it that I'm using throughout my app. I'd like to be able to call a function from the actor when I receive a Notification from NotificationCenter, but can't call async functions from sink.
This is what I'm doing now:
class MyClass {
private var cancellables: [AnyCancellable] = []
init() {
NotificationCenter.default.publisher(for: NotificationName)
.receive(on: DispatchQueue.global(qos: .utility))
.compactMap { $0 as? SomeType }
.sink { [weak self] val in
Task { [weak self] in
await self?.someCallToActor(val)
}
}.store(in: &cancellables)
}
@SomeGlobalActor
func someCallToActor(_ val: String) async {
await SomeGlobalActor.shared.actorMethod(val)
}
}
...
@globalActor
actor SomeGlobalActor {
static var shared = SomeGlobalActor()
func actorMethod(_ val: String) async {
...
}
}
Calling Task
within a closure here feels wrong and potentially race-condition-y. Is this the best way to accomplish what I'm trying to? I've tried receiving the notifications inside of the actor itself but it doesn't change much. The issue is the closure provided to sink is meant to be synchronous so I can't await
inside of it.