I have a feeling that Swift Concurrency is fighting agains me all the time. It is really frustrating.
My problem. I need to create Combine publisher to emit battery state on iOS device.
So far I have this:
extension Notification.Name {
var publisher: NotificationCenter.Publisher {
return NotificationCenter.default.publisher(for: self)
}
}
func createDefaultPublisher() -> AnyPublisher<Float, Never> {
UIDevice.batteryLevelDidChangeNotification
.publisher
.compactMap { $0.object as? UIDevice }
.map { device in
Future<Float, Never> { promise in
Task { @MainActor in
promise(.success(device.batteryLevel)) // Sending 'promise' risks causing data races
}
}
}
.switchToLatest()
.eraseToAnyPublisher()
}
So the tricky part for me is how to implement map operator. I need to switch to the MainActor there so I'm using Future with promise callback. The problem here is: Sending 'promise' risks causing data races. So I wondering how to do it properly in Swift 6 in project configured with Complete Strict Concurrency Checking
AsyncSequenceof your ownSendabletypeSendabletype. ThebatteryLevelis alreadySendable.