@FetchAll does not load/display data initially when the parent view has a @Environment(\.scenePhase) property #207
-
DescriptionHey, so I've come across a super strange and specific bug. It might be a SwiftUI bug, but I wanted to report it here to be sure. I have a fairly simple setup (I've recreated it in an example project that I attached below): @Table
struct Memory: Hashable, Codable {
let id: UUID
var name: String
var tagId: UUID
}
@Table
struct Tag: Hashable, Codable {
let id: UUID
var name: String
}
@Selection
struct MemoryInfo: Identifiable, Hashable, Codable {
var id: UUID { memory.id }
var memory: Memory
var tag: Tag
init(memory: Memory, tag: Tag) {
self.memory = memory
self.tag = tag
}
}Then, I have a SwiftUI view that loads some data using struct TestView: View {
@State private var reloadId: UUID = .init()
@FetchAll private var memories: [MemoryInfo]
var body: some View {
Group {
List {
Button("Reload") {
reloadId = UUID()
}
ForEach(memories) { memoryInfo in
Text(memoryInfo.memory.name)
}
}
}
.task(id: reloadId) {
try! await $memories.load(
Memory
.join(Tag.all) { $0.tagId.eq($1.id) }
.select { MemoryInfo.Columns(memory: $0, tag: $1) }
)
}
}
}(In my actual project, the query has some This is working totally fine and as expected. The view is shown with the correct list of memories. However, once you embed struct ContentView: View {
// If you comment out this line, the @FetchAll above succeeds when the view appears
@Environment(\.scenePhase) private var scenePhase
var body: some View {
TestView()
}
}Triggering a reload by pressing the "Reload" button fixes this and the data is correctly loaded and displayed. But it is never displayed when the view first appears. This only happens with the This is pretty strange 😅 Do you have any idea what's going on here? Checklist
Expected behaviorThe view should be presented with the loaded data (in this example, there is only one row in the database):
Actual behaviorThe view is presented with an empty list:
Reproducing projecthttps://github.com/SwiftedMind/FetchAllDemo SharingGRDB version information1.0.0 Sharing version information2.7.4 GRDB version information7.6.1 Destination operating systemiOS 26.0 Xcode version informationXcode 26.0 Swift Compiler version informationswift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
Target: arm64-apple-macosx26.0 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
This definitely looks like a SwiftUI bug to me, so I've converted to a discussion. Luckily there appear to be 2 workarounds:
|
Beta Was this translation helpful? Give feedback.


This definitely looks like a SwiftUI bug to me, so I've converted to a discussion.
Luckily there appear to be 2 workarounds:
@State @FetchAll, which creates a stronger bond between our property wrapper and the view. The caveat is it can be cumbersome to work with nested property wrappers: you need to assign an explicit[]default to the property, and you need to go through$fetch.wrappedValue.loadand other endpoints on the@FetchAll.@FetchAllinto a model class and use@State var model: Modelin the view. This is probably more ergonomic and tends to have less buggy interactions with SwiftUI.