I’ve such protocol not owned by my codebase. It got here from library. I extracted it to reveal minimal simply to deal with one drawback.
protocol BatteryLevelProvider {
func getBatteryLevel() -> Float
}
Now I must implement this protocol and in its technique I must entry to MainActor to get present UIDevice batteryLevel.
last class BaseBatteryLevelProvider: BatteryLevelProvider {
func getBatteryLevel() -> Float {
// The best way to entry to the MainActor in sync approach. One potential approach that I am excited about is like this:
let isOnMainQueue: Bool = Thread.isMainThread
if isOnMainQueue {
return MainActor.assumeIsolated {
return UIDevice.present.batteryLevel
}
} else {
return DispatchQueue.foremost.sync {
MainActor.assumeIsolated {
return UIDevice.present.batteryLevel
}
}
}
}
}
So mainly I am pondering easy methods to entry to the MainActor isolation area from nonisolated technique however in blocking/sync approach to get worth of the batterlyLevel and return this worth in sync approach. If already on MainQueue I mustn’t use sync as a result of it would trigger Impasse. Is there any approach how can I examine conditionally if code is already operating on MainQueue?
Different potential options. Mark technique with MainActor macro and use preconcurrency:
class BaseBatteryLevelProvider: @preconcurrency BatteryLevelProvider {
@MainActor
func getBatteryLevel() -> Float {
UIDevice.present.batteryLevel
}
}
However the compiler won’t warn me after I’m not in MainActor context:
nonisolated func take a look at() {
let batteryMonitor: BatteryLevelProvider = BaseBatteryLevelProvider()
let degree = batteryMonitor.getBatteryLevel()
}
My foremost doubts are that I am unsure whether it is save to examine if I am on MainQueue with the assistance of Thread.isMainThread or if there’s a higher devoted approach in Swift Concurrency to do it that can assist me implement this 3’rd celebration protocol.