Question about async execution, Swift 6, and strict concurrency (macOS app). I also have limited knowledge of Swift concurrency, but I learn something new every time I explore it.
I have two solutions for observing notifications:
- Combine publisher and
- adding observers to the NotificationCenter.
Xcode is set to Swift 6 language mode and strict concurrency checking, and compiles without warnings and runs as expected.
But, why does closure for NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable complain about main actor isolated property can't be mutated from a nonisolated context, while Combine publisher doesn't when updating properties from within the closures?
Both classes run on the main thread. Below are two snippets of code:
// Combine Publisher
NotificationCenter.default.publisher(
for: NSNotification.Name.NSFileHandleDataAvailable)
.sink { [self] _ in
let data = outHandle.availableData
if data.count > 0 {
...
}
outHandle.waitForDataInBackgroundAndNotify()
}
}.store(in: &subscriptons)
The closure for NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable) requires an async closure to update properties to compile and run.
// Observers
var notificationsfilehandle: NSObjectProtocol?
....
notificationsfilehandle =
NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable,
object: nil, queue: nil)
{ _ in
Task {
await self.datahandle(pipe)
}
}
func datahandle(_ pipe: Pipe) async { ... }