Search code examples
swiftuibackgroundcrashswiftdata

Background crash: _SwiftData_SwiftUI: one-time initialization function for empty


I'm using SwiftData & SwiftUI and my App keeps crashing in the background. I sadly can't reproduce it, I'm only seeing the TestFlight crash reports.

These are my observations so far:

  • Having either Background fetch and/or Remote Notifications (for CloudKit) on leads to the issue; only if I turn off both is the issue gone
  • If I turn on Background fetch, even if I don't add any code to run in the background (so no .backgroundTask, no task scheduling via BGAppRefreshTaskRequest) the App is still crashing, so it doesn't seem to matter what or if I do anything in the background myself
  • I'm not sure about this, but from reports it seems that the issue could be related to using two devices with the App installed, someone reported that the App was running on the iPad and then crashed on the iPhone even though the app wasn't running there and the iPad version had no issues
  • It only seems to crash after some time, never when the App is open and afaik not immediately after closing the App

This is the Xcode crash report:

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019dd618c0
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [622]

Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   libswiftCore.dylib              0x000000019dd618c0 _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:144)
1   libswiftCore.dylib              0x000000019ddcfd14 swift_unexpectedError + 664 (ErrorType.swift:188)
2   _SwiftData_SwiftUI              0x000000023fd20d78 one-time initialization function for empty + 300 (ModelContainer+Extensions.swift:5)
3   libdispatch.dylib               0x00000001a7312dd4 _dispatch_client_callout + 20 (object.m:576)
4   libdispatch.dylib               0x00000001a7314654 _dispatch_once_callout + 32 (once.c:52)
5   _SwiftData_SwiftUI              0x000000023fd20df8 one-time initialization function for empty + 124 (ModelContainer+Extensions.swift:12)
6   libdispatch.dylib               0x00000001a7312dd4 _dispatch_client_callout + 20 (object.m:576)
7   libdispatch.dylib               0x00000001a7314654 _dispatch_once_callout + 32 (once.c:52)
8   _SwiftData_SwiftUI              0x000000023fd36170 key path getter for EnvironmentValues.modelContext : EnvironmentValues + 140 (<compiler-generated>:0)
9   libswiftCore.dylib              0x000000019de8c628 RawKeyPathComponent._projectReadOnly<A, B, C>(_:to:endingWith:) + 1012 (KeyPath.swift:1701)
10  libswiftCore.dylib              0x000000019de8bddc KeyPath._projectReadOnly(from:) + 1036 (KeyPath.swift:331)
11  libswiftCore.dylib              0x000000019de90348 swift_getAtKeyPath + 24 (KeyPath.swift:2029)
12  SwiftUI                         0x00000001a3c9c814 EnvironmentBox.update(property:phase:) + 872 (Environment.swift:273)
13  SwiftUI                         0x00000001a39d2074 static BoxVTable.update(ptr:property:phase:) + 396 (DynamicPropertyBuffer.swift:294)
14  SwiftUI                         0x00000001a39d17b0 _DynamicPropertyBuffer.update(container:phase:) + 104 (DynamicPropertyBuffer.swift:215)
15  SwiftUI                         0x00000001a4a27b78 closure #1 in closure #1 in DynamicBody.updateValue() + 104 (DynamicProperty.swift:447)
16  SwiftUI                         0x00000001a4a27bb8 partial apply for closure #1 in closure #1 in DynamicBody.updateValue() + 28 (<compiler-generated>:0)
17  libswiftCore.dylib              0x000000019dd74068 withUnsafeMutablePointer<A, B>(to:_:) + 28 (LifetimeManager.swift:82)
18  SwiftUI                         0x00000001a4a279dc closure #1 in DynamicBody.updateValue() + 408 (DynamicProperty.swift:446)
19  SwiftUI                         0x00000001a4a275c0 DynamicBody.updateValue() + 712 (DynamicProperty.swift:445)
20  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
21  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
22  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
23  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
24  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
25  SwiftUI                         0x00000001a4a27548 DynamicBody.updateValue() + 592 (DynamicProperty.swift:444)
26  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
27  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
28  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
29  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
30  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
31  SwiftUI                         0x00000001a44b73ac Attribute.syncMainIfReferences<A>(do:) + 236 (AttributeGraphAdditions.swift:84)
32  SwiftUI                         0x00000001a42cd0f8 closure #1 in GeometryReader.Child.updateValue() + 108 (GeometryReader.swift:85)
33  SwiftUI                         0x00000001a42ce8ac partial apply for closure #1 in GeometryReader.Child.updateValue() + 24 (<compiler-generated>:0)
34  SwiftUI                         0x00000001a3c1f7d0 closure #1 in _withObservation<A>(do:) + 44 (ObservationUtils.swift:26)
35  SwiftUI                         0x00000001a42ce8cc partial apply for closure #1 in _withObservation<A>(do:) + 24 (<compiler-generated>:0)
36  libswiftCore.dylib              0x000000019dd74068 withUnsafeMutablePointer<A, B>(to:_:) + 28 (LifetimeManager.swift:82)
37  SwiftUI                         0x00000001a42ccd88 GeometryReader.Child.updateValue() + 1108 (GeometryReader.swift:84)
38  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
39  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
40  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
41  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
42  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
43  SwiftUI                         0x00000001a4347c40 DynamicViewContainer.view.getter + 48
44  SwiftUI                         0x00000001a4347ef0 DynamicViewList.updateValue() + 424 (DynamicView.swift:147)
45  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
46  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
47  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
48  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
49  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
50  SwiftUI                         0x00000001a41dd204 specialized implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 168 (<compiler-generated>:0)
51  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
52  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
53  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
54  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
55  SwiftUI                         0x00000001a38b2598 DynamicLayoutViewAdaptor.updatedItems() + 68 (DynamicLayoutView.swift:166)
56  SwiftUI                         0x00000001a35e9efc specialized DynamicContainerInfo.updateItems(disableTransitions:) + 68 (DynamicContainer.swift:468)
57  SwiftUI                         0x00000001a35e8e98 specialized DynamicContainerInfo.updateValue() + 376 (DynamicContainer.swift:326)
58  SwiftUI                         0x00000001a37b304c specialized implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 24 (<compiler-generated>:0)
59  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
60  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
61  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
62  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
63  SwiftUI                         0x00000001a3cbcd34 DynamicPreferenceCombiner.info.getter + 96 (DynamicContainer.swift:0)
64  SwiftUI                         0x00000001a3cbcf4c DynamicPreferenceCombiner.value.getter + 228 (DynamicContainer.swift:877)
65  SwiftUI                         0x00000001a347b0ac implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 324 (<compiler-generated>:0)
66  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
67  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
68  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
69  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
70  SwiftUI                         0x00000001a395ed70 HostPreferencesTransform.updateValue() + 104 (PreferenceTransformModifier.swift:123)
71  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
72  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
73  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
74  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
75  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
76  SwiftUI                         0x00000001a395ed70 HostPreferencesTransform.updateValue() + 104 (PreferenceTransformModifier.swift:123)
77  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
78  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
79  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
80  AttributeGraph                  0x00000001c7eea810 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, unsigned int, AGSwiftMetadata const*, unsigned char&, long) + 720 (ag-graph.cc:1429)
81  AttributeGraph                  0x00000001c7eea3a4 AGGraphGetValue + 228 (AGGraph.mm:701)
82  SwiftUI                         0x00000001a395ed70 HostPreferencesTransform.updateValue() + 104 (PreferenceTransformModifier.swift:123)
83  SwiftUI                         0x00000001a3390bf8 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
84  AttributeGraph                  0x00000001c7ef4240 AG::Graph::UpdateStack::update() + 512 (ag-graph-update.cc:578)
85  AttributeGraph                  0x00000001c7eeaf38 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 (ag-graph-update.cc:719)
86  AttributeGraph                  0x00000001c7ef2538 AG::Graph::value_ref(AG::AttributeID, unsigned int, AGSwiftMetadata const*, unsigned char&) + 288 (ag-graph.cc:1201)
87  AttributeGraph                  0x00000001c7ef5470 AGGraphGetWeakValue + 388 (AGGraph.mm:735)
88  SwiftUI                         0x00000001a48b0424 GraphHost.updatePreferences() + 48 (GraphHost.swift:773)
89  SwiftUI                         0x00000001a3ed2940 ViewGraph.updateOutputs() + 300 (ViewGraph.swift:614)
90  SwiftUI                         0x00000001a4983674 closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 1268 (ViewRendererHost.swift:243)
91  SwiftUI                         0x00000001a4983028 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 660 (ViewRendererHost.swift:235)
92  SwiftUI                         0x00000001a4981170 ViewRendererHost.render(interval:updateDisplayList:) + 408 (<compiler-generated>:0)
93  SwiftUI                         0x00000001a39192d4 closure #1 in _UIHostingView.requestImmediateUpdate() + 72 (_UIHostingView.swift:701)
94  SwiftUI                         0x00000001a49ee690 thunk for @escaping @callee_guaranteed () -> () + 36
95  libdispatch.dylib               0x00000001a731113c _dispatch_call_block_and_release + 32 (init.c:1530)
96  libdispatch.dylib               0x00000001a7312dd4 _dispatch_client_callout + 20 (object.m:576)
97  libdispatch.dylib               0x00000001a73215a4 _dispatch_main_queue_drain + 988 (queue.c:7898)
98  libdispatch.dylib               0x00000001a73211b8 _dispatch_main_queue_callback_4CF + 44 (queue.c:8058)
99  CoreFoundation                  0x000000019f44d51c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1780)
100 CoreFoundation                  0x000000019f44a218 __CFRunLoopRun + 1996 (CFRunLoop.c:3149)
101 CoreFoundation                  0x000000019f449968 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420)
102 GraphicsServices                0x00000001e37474e0 GSEventRunModal + 164 (GSEvent.c:2196)
103 UIKitCore                       0x00000001a18bcedc -[UIApplication _run] + 888 (UIApplication.m:3692)
104 UIKitCore                       0x00000001a18bc518 UIApplicationMain + 340 (UIApplication.m:5282)
105 SwiftUI                         0x00000001a4283860 closure #1 in KitRendererCommon(_:) + 168 (UIKitApp.swift:51)
106 SwiftUI                         0x00000001a42836a8 runApp<A>(_:) + 152 (UIKitApp.swift:14)
107 SwiftUI                         0x00000001a3e9f9fc static App.main() + 132 (App.swift:114)
108 Unwatched                       0x000000010285aa64 static UnwatchedApp.$main() + 52 (UnwatchedApp.swift:0)
109 Unwatched                       0x000000010285aa64 main + 64
110 dyld                            0x00000001c296ad84 start + 2240 (dyldMain.cpp:1298)

This is the Sentry crash report:

I've added Sentry to the project, hoping it would give me more details on the crash. This seems to be the same crash, here's the full crashlog.

EXC_BREAKPOINT
_SwiftData_SwiftUI/ModelContainer+Extensions.swift > 'try!' expression unexpectedly raised an error:  > 'try!' expression unexpectedly raised an error: SwiftData.SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer) > Fatal error >
Stack overflow in (null)

Is anyone seeing a similar crash? Could this be a SwiftData/SwiftUI Bug?

I'm grateful for any ideas on what I could try or where the issue could be coming from.


Solution

  • Thanks to Brian, I think I finally figgured it out!

    This Apple Developer Thread has a similar issue, it seems to be a SwiftUI bug. When the App launches in the background from being inactive, it’s crashing when an @Environment variable is used in the root ContentView (only seems to happen for .modelContext for me).

    I was able to reliably reproduce it by launching the App in the background directly.

    This is what I was doing:

    @main
    struct MyApp: App {
        var sharedModelContainer: ModelContainer = {
            // ...
        }()
        
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
            .modelContainer(sharedModelContainer)
        }
    }
    
    struct ContentView: View {
        @Environment(\.modelContext) var modelContext
    
        var body: some View {
            MyView()
        }
        
        func someFunc() {
            modelContext.insert(...)
        }
    }
    

    As a workaround, I’m now passing the container to the root view as an argument and adding it there via .modelContainer(...), which seems to avoid the issue:

    @main
    struct MyApp: App {
        var sharedModelContainer: ModelContainer = {
            // ...
        }()
        
        var body: some Scene {
            WindowGroup {
                ContentView(container: sharedModelContainer)
            }
        }
    }
    
    struct ContentView: View {
        let container: ModelContainer
        
        var body: some View {
            MyView()
                .modelContainer(container)
        }
        
        func someFunc() {
            let modelContext = ModelContext(container)
            modelContext.insert(...)
        }
    }