-
|
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 : SendableNo 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.SendableThe 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
refreshableclosure is marked as@Sendableas 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 forbackgroundTaskbut notrefreshable.Well, to figure out why we had to go all the way into the
.swiftinterfacefile, and there we can see a big diff…