I have a ViewBuilder
that I use to lock/unlock some views. It uses a Binding
to pass the locked/unlocked State
.
I am now getting this warning on the if
line:
Capture of 'isUnlocked' with non-sendable type 'Binding' in a
@Sendable
closure
extension View {
@ViewBuilder
func requestUnlock(isUnlocked: Binding<Bool>) -> some View {
self.task {
if isUnlocked.wrappedValue == false {
let unlocked = await Unlock.authenticate()
isUnlocked.wrappedValue = unlocked
}
}
}
}
As this is an extension of View
I cannot add or ignore Sendable
compliance and i'm not sure what magic is needed for me to clear this warning.
Create a view modifier instead and let SwiftUI handle the updates and actor isolation for you via the property wrapper:
struct UnlockRequester: ViewModifier {
@Binding var isUnlocked: Bool
func body(content: Content) -> some View {
content.task {
if isUnlocked == false {
isUnlocked = await Unlock.authenticate()
}
}
}
}
Then:
extension View {
func requestUnlock(isUnlocked: Binding<Bool>) -> some View {
self.modifier(UnlockRequester(isUnlocked: isUnlocked))
}
}
This gives no warnings even with strict concurrency checking enabled.