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 methodology I must entry to MainActor to get present UIDevice batteryLevel.
last class BaseBatteryLevelProvider: BatteryLevelProvider {
func getBatteryLevel() -> Float {
// Tips on how to entry to the MainActor in sync manner. One attainable manner 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.important.sync {
MainActor.assumeIsolated {
return UIDevice.present.batteryLevel
}
}
}
}
}
So principally I am considering how one can entry to the MainActor isolation area from nonisolated methodology however in blocking/sync strategy to get worth of the batterlyLevel and return this worth in sync manner. If already on MainQueue I mustn’t use sync as a result of it should trigger Impasse. Is there any manner how can I examine conditionally if code is already operating on MainQueue?
Different attainable options. Mark methodology with MainActor macro and use preconcurrency:
class BaseBatteryLevelProvider: @preconcurrency BatteryLevelProvider {
@MainActor
func getBatteryLevel() -> Float {
UIDevice.present.batteryLevel
}
}
However the compiler is not going to warn me once I’m not in MainActor context:
nonisolated func take a look at() {
let batteryMonitor: BatteryLevelProvider = BaseBatteryLevelProvider()
let degree = batteryMonitor.getBatteryLevel()
}
My important doubts are that I am undecided whether it is save to examine if I am on MainQueue with the assistance of Thread.isMainThread or if there’s a higher devoted manner in Swift Concurrency to do it that can assist me implement this 3’rd get together protocol.