Crash After Presenting SwiftUI Alert

I’m seeing a crash in production for a small percentage of users, and have narrowed it down based on logging to happening as or very shortly after an alert is presented using SwiftUI.

This seems to be isolated to iOS 17.5.1, but since it’s a low-volume crash I can’t be sure there aren’t other affected versions. What can I understand from the crash report?

Here’s a simplified version of the code which presents the alert, which seems so simple I can’t understand why it would crash. And following that is the crash trace.


// View (simplified)

@MainActor public struct MyView: View {
    @ObservedObject var model: MyViewModel

    public init(model: MyViewModel) { 
        self.model = model 
    }

    public var body: some View {
        myViewContent
            .overlay(clearAlert)
    }

    var clearAlert: some View {
        EmptyView().alert(
            "Are You Sure?",
            isPresented: $model.isClearAlertVisible,
            actions: {
                Button("Keep", role: .cancel) { model.clearAlertKeepButtonWasPressed() }
                Button("Delete", role: .destructive) { model.clearAlertDeleteButtonWasPressed() }
            },
            message: {
                Text("This cannot be undone.")
            }
        )
    }
}

// Model (simplified)

@MainActor public final class MyViewModel: ObservableObject {
    @Published var isClearAlertVisible = false

    func clearButtonWasPressed() {
        isClearAlertVisible = true
    }

    func clearAlertKeepButtonWasPressed() {
        // No-op.
    }

    func clearAlertDeleteButtonWasPressed() {
        // Calls other code.
    }
}

Incident Identifier: 36D05FF3-C64E-4327-8589-D8951C8BAFC4
Distributor ID:      com.apple.AppStore
Hardware Model:      iPhone13,2
Process:             My App [379]
Path:                /private/var/containers/Bundle/Application/B589E780-96B2-4A5F-8FCD-8B34F2024595/My App.app/My App
Identifier:          com.me.MyApp
Version:             1.0 (1)
AppStoreTools:       15F31e
AppVariant:          1:iPhone13,2:15
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.me.MyApp [583]

Date/Time:           2024-06-21 20:09:20.9767 -0500
Launch Time:         2024-06-20 18:41:01.7542 -0500
OS Version:          iPhone OS 17.5.1 (21F90)
Release Type:        User
Baseband Version:    4.50.06
Report Version:      104

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

Triggered by Thread:  0

Kernel Triage:
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter
VM - (arg = 0x3) mach_vm_allocate_kernel failed within call to vm_map_enter

Thread 0 name:
Thread 0 Crashed:
0   libswiftCore.dylib            	0x00000001a69998c0 _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:144)
1   AttributeGraph                	0x00000001d0cd61a4 Attribute.init<A>(body:value:flags:update:) + 352 (Attribute.swift:473)
2   SwiftUI                       	0x00000001ac034054 closure #1 in Attribute.init<A>(_:) + 128 (<compiler-generated>:0)
3   SwiftUI                       	0x00000001ac033cac partial apply for closure #1 in Attribute.init<A>(_:) + 32 (<compiler-generated>:0)
4   libswiftCore.dylib            	0x00000001a6ad0450 withUnsafePointer<A, B>(to:_:) + 28 (LifetimeManager.swift:128)
5   SwiftUI                       	0x00000001ad624d14 closure #2 in UIKitDialogBridge.startTrackingUpdates(actions:) + 268 (UIKitDialogBridge.swift:370)
6   SwiftUI                       	0x00000001ad624ae0 UIKitDialogBridge.startTrackingUpdates(actions:) + 248 (UIKitDialogBridge.swift:369)
7   SwiftUI                       	0x00000001ad6250cc closure #4 in UIKitDialogBridge.showNewAlert(_:id:) + 72 (UIKitDialogBridge.swift:471)
8   SwiftUI                       	0x00000001abfdd050 thunk for @escaping @callee_guaranteed () -> () + 36 (:-1)
9   UIKitCore                     	0x00000001aa5722e4 -[UIPresentationController transitionDidFinish:] + 1096 (UIPresentationController.m:651)
10  UIKitCore                     	0x00000001aa571d88 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.114 + 320 (UIPresentationController.m:1390)
11  UIKitCore                     	0x00000001aa5cb9ac -[_UIViewControllerTransitionContext completeTransition:] + 116 (UIViewControllerTransitioning.m:304)
12  UIKitCore                     	0x00000001aa34a91c __UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK__ + 36 (UIView.m:16396)
13  UIKitCore                     	0x00000001aa34a800 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 624 (UIView.m:16429)
14  UIKitCore                     	0x00000001aa349518 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 436 (UIView.m:0)
15  UIKitCore                     	0x00000001aa356b14 -[UIViewAnimationState animationDidStop:finished:] + 192 (UIView.m:2400)
16  UIKitCore                     	0x00000001aa356b84 -[UIViewAnimationState animationDidStop:finished:] + 304 (UIView.m:2422)
17  QuartzCore                    	0x00000001a96f8c50 run_animation_callbacks(void*) + 132 (CALayer.mm:7714)
18  libdispatch.dylib             	0x00000001aff61dd4 _dispatch_client_callout + 20 (object.m:576)
19  libdispatch.dylib             	0x00000001aff705a4 _dispatch_main_queue_drain + 988 (queue.c:7898)
20  libdispatch.dylib             	0x00000001aff701b8 _dispatch_main_queue_callback_4CF + 44 (queue.c:8058)
21  CoreFoundation                	0x00000001a808f710 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1780)
22  CoreFoundation                	0x00000001a808c914 __CFRunLoopRun + 1996 (CFRunLoop.c:3149)
23  CoreFoundation                	0x00000001a808bcd8 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420)
24  GraphicsServices              	0x00000001ecf3c1a8 GSEventRunModal + 164 (GSEvent.c:2196)
25  UIKitCore                     	0x00000001aa6c490c -[UIApplication _run] + 888 (UIApplication.m:3713)
26  UIKitCore                     	0x00000001aa7789d0 UIApplicationMain + 340 (UIApplication.m:5303)
27  SwiftUI                       	0x00000001ac27c148 closure #1 in KitRendererCommon(_:) + 168 (UIKitApp.swift:51)
28  SwiftUI                       	0x00000001ac228714 runApp<A>(_:) + 152 (UIKitApp.swift:14)
29  SwiftUI                       	0x00000001ac2344d0 static App.main() + 132 (App.swift:114)
30  My App                          0x00000001001e7bfc static MyApp.$main() + 52 (MyApp.swift:0)
31  My App                         	0x00000001001e7bfc main + 64
32  dyld                          	0x00000001cb73de4c start + 2240 (dyldMain.cpp:1298)

The only other piece of information I have is the crash_info_entry_0, which is as follows:

AttributeGraph/Attribute.swift:473: Fatal error: attempting to create attribute with no subgraph: UpdateAlertActions

Ok, I finally saw a runtime warning in debug when presenting the alert, which is something to go on. But why would this warning be issued? My view model is marked @MainActor.

Publishing changes from within view updates is not allowed, this will cause undefined behavior.

have exact same issues. Did you manage to solve? @34534543456789098767654

Crash After Presenting SwiftUI Alert
 
 
Q