-
Hello, I've been experimenting with getting TCA's new concurrency APIs integrated with the new background refresh APIs in iOS 16. This API is a bit like last year's struct MyScene: Scene {
@Environment(\.scenePhase) private var scenePhase
let store: Store<SceneState, SceneAction>
var body: some Scene {
WithViewStore(self.store) { viewStore in
WindowGroup {
EmptyView()
.refreshable {
await viewStore.send(.refresh).finish() // no warning
}
}
.backgroundTask(.appRefresh("my-background-task-identifier")) {
await viewStore.send(.backgroundTask).finish() // ⚠️ Capture of 'viewStore' with non-sendable type 'ViewStore<SceneState, SceneAction>' in a `@Sendable` closure
}
.onChange(of: self.scenePhase) { viewStore.send(.didChange(scenePhase: $0)) }
}
}
} My intuition here is to mark the closure I'm providing as @ MainActor, since it's going to be capturing the view store. Is this the correct fix? - .backgroundTask(.appRefresh("my-background-task-identifier")) {
+ .backgroundTask(.appRefresh("my-background-task-identifier")) { @MainActor in
await viewStore.send(.backgroundTask).finish()
} Looking at the documentation, neither |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Although the docs say that public func backgroundTask<D, R>(_ task: BackgroundTask<D, R>, action: @escaping @Sendable (D) async -> R) -> some Scene where D : Sendable, R : Sendable No idea why the docs are wrong, but maybe a feedback should be filed. Also, even the Well, to figure out why we had to go all the way into the public func refreshable(@_inheritActorContext action: @escaping @Sendable () async -> Swift.Void) -> some SwiftUI.View
public func backgroundTask<D, R>(_ task: SwiftUI.BackgroundTask<D, R>, action: @escaping @Sendable (D) async -> R) -> some SwiftUI.Scene where D : Swift.Sendable, R : Swift.Sendable The So, for now I do believe the best solution is to just mark the closure of |
Beta Was this translation helpful? Give feedback.
Although the docs say that
backgroundTask
's closure isn't@Sendable
, it does seem to be the case in the Swift headers:No idea why the docs are wrong, but maybe a feedback should be filed.
Also, even the
refreshable
closure is marked as@Sendable
as can be seen in the Swift headers, but again the docs report it as being merely@escaping
. So, it seems weird that we get the sendable warning forbackgroundTask
but notrefreshable
.Well, to figure out why we had to go all the way into the
.swiftinterface
file, and there we can see a big diff…