Skip to content

Crash when selecting icon in RichTextKeyboardToolbat #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
TheApApp opened this issue Apr 3, 2025 · 5 comments
Open

Crash when selecting icon in RichTextKeyboardToolbat #236

TheApApp opened this issue Apr 3, 2025 · 5 comments
Labels
discussion Discussions not yet turned into an action

Comments

@TheApApp
Copy link

TheApApp commented Apr 3, 2025

I've been looking at leveraging RichTextEdit, however, when ever I add the RichTextKeyboardToolbar to my view, it crashes if I try either of the two presented buttons. The crash when running on an actual device is

UITextView 0x10e895800 is switching to TextKit 1 compatibility mode because its layoutManager was accessed. Break on void _UITextViewEnablingCompatibilityMode(UITextView *__strong, BOOL) to debug.
App is being debugged, do not track this hang
Hang detected: 1.49s (debugger attached, not reporting)
App is being debugged, do not track this hang
Hang detected: 1.21s (debugger attached, not reporting)
*** Assertion failure in void BUG_IN_CLIENT_OF_TARGETED_PREVIEW__VIEW_IS_NOT_IN_A_WINDOW(Class  _Nonnull __unsafe_unretained, UIView * _Nonnull __strong)(), UITargetedPreview.m:70
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This UITargetedPreview initializer requires that the view is in a window, but it is not. Either fix that, or use the other initializer that takes a target with an explicit container. (view: <_TtC7SwiftUIP33_64A26C7A8406856A733B1A7B593971F725UIKitIconPreferringButton: 0x10540ed00> → <_TtGC7SwiftUI16PlatformViewHostGVS_P10$190cd383832PlatformViewRepresentableAdaptorGVS_P10$190c72a3418UIKitButtonAdaptorVS_P10$190c72ba019PlatformItemContent___: 0x10f625680>)'
*** First throw call stack:
(0x18b4812ec 0x188905a7c 0x18a77e040 0x18e857160 0x18e8571d4 0x18f27a4a4 0x18ed7a4f8 0x18ed7769c 0x18f27a0b8 0x18f27d12c 0x18f27d1cc 0x18f27d014 0x18f279ff0 0x18e7e2ab8 0x18e6c28cc 0x18e68b7c4 0x18df8c3a8 0x18e6b3d40 0x18e6b4000 0x18deb855c 0x18deb855c 0x18deb855c 0x18deb855c 0x18dcb3bdc 0x18dcb1e44 0x18dd2802c 0x18deb8c34 0x18deb76f0 0x18deb6658 0x18de7b7c4 0x18ddfa0b8 0x18dd18c10 0x18dd1604c 0x18dd17b64 0x18dd167dc 0x18b3d9ce4 0x18b3d9c78 0x18b3d89fc 0x18b3d7c3c 0x18b3fc700 0x1d7f3d190 0x18e01a240 0x18e018470 0x18fc74f3c 0x18fc74e6c 0x18fc74d50 0x1016969c4 0x101696ac4 0x1b1dffad8)
libc++abi: terminating due to uncaught exception of type NSException

And when I run it in the simulator I get:

*** First throw call stack:
(
	0   CoreFoundation                      0x00000001804c88c0 __exceptionPreprocess + 172
	1   libobjc.A.dylib                     0x00000001800937cc objc_exception_throw + 72
	2   Foundation                          0x0000000180e6999c -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
	3   UIKitCore                           0x00000001855323ec BUG_IN_CLIENT_OF_TARGETED_PREVIEW__VIEW_IS_NOT_IN_A_WINDOW + 140
	4   UIKitCore                           0x000000018553244c -[UITargetedPreview initWithView:] + 64
	5   UIKitCore                           0x00000001861d17fc -[UIContextMenuInteraction clickPresentationInteraction:previewForHighlightingAtLocation:] + 124
	6   UIKitCore                           0x0000000185b6ba54 -[_UIClickPresentationInteraction _prepareInteractionEffect] + 136
	7   UIKitCore                           0x0000000185b68498 -[_UIClickPresentationInteraction _performPreviewPresentation] + 36
	8   UIKitCore                           0x00000001861d1410 __53-[UIContextMenuInteraction _presentMenuAtLocation3D:]_block_invoke + 40
	9   UIKitCore                           0x00000001861d4288 __70-[UIContextMenuInteraction _interactionShouldBeginAtPoint:completion:]_block_invoke + 208
	10  UIKitCore                           0x00000001861d42fc __70-[UIContextMenuInteraction _interactionShouldBeginAtPoint:completion:]_block_invoke_2 + 92
	11  UIKitCore                           0x00000001861d4174 -[UIContextMenuInteraction _interactionShouldBeginAtPoint:completion:] + 332
	12  UIKitCore                           0x00000001861d134c -[UIContextMenuInteraction _presentMenuAtLocation3D:] + 416
	13  UIKitCore                           0x00000001854a1168 -[UIControl performPrimaryAction] + 144
	14  UIKitCore                           0x00000001852fecbc -[UICollectionViewCell _performCustomSelectionAction] + 32
	15  UIKitCore                           0x00000001852977e0 -[UICollectionViewListCell _performCustomSelectionAction] + 120
	16  UIKitCore                           0x00000001852b9270 -[UICollectionView _selectItemAtIndexPath:animated:scrollPosition:notifyDelegate:deselectPrevious:performPrimaryAction:performCustomSelectionAction:] + 112
	17  UIKitCore                           0x00000001852e98f0 -[UICollectionView _userSelectItemAtIndexPath:animatedSelection:] + 240
	18  UIKitCore                           0x00000001852e9b84 -[UICollectionView touchesEnded:withEvent:] + 444
	19  UIKitCore                           0x0000000185bf9a98 forwardTouchMethod + 352
	20  UIKitCore                           0x0000000185bf9a98 forwardTouchMethod + 352
	21  UIKitCore                           0x0000000185bf9a98 forwardTouchMethod + 352
	22  UIKitCore                           0x0000000185bf9a98 forwardTouchMethod + 352
	23  UIKitCore                           0x0000000185c07e24 -[UIWindow _sendTouchesForEvent:] + 976
	24  UIKitCore                           0x0000000185c0922c -[UIWindow sendEvent:] + 2820
	25  UIKitCore                           0x0000000185be8bfc -[UIApplication sendEvent:] + 376
	26  UIKit                               0x00000001ccc1a870 -[UIApplicationAccessibility sendEvent:] + 100
	27  UIKitCore                           0x0000000185c731bc __dispatchPreprocessedEventFromEventQueue + 1160
	28  UIKitCore                           0x0000000185c75e60 __processEventQueue + 4800
	29  UIKitCore                           0x0000000185c6e474 updateCycleEntry + 156
	30  UIKitCore                           0x0000000185133f04 _UIUpdateSequenceRun + 76
	31  UIKitCore                           0x0000000185afd9b8 schedulerStepScheduledMainSection + 204
	32  UIKitCore                           0x0000000185afcdd4 runloopSourceCallback + 80
	33  CoreFoundation                      0x00000001804284b8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
	34  CoreFoundation                      0x0000000180428400 __CFRunLoopDoSource0 + 168
	35  CoreFoundation                      0x0000000180427b88 __CFRunLoopDoSources0 + 220
	36  CoreFoundation                      0x0000000180422584 __CFRunLoopRun + 780
	37  CoreFoundation                      0x0000000180421e3c CFRunLoopRunSpecific + 536
	38  GraphicsServices                    0x0000000190f62d00 GSEventRunModal + 164
	39  UIKitCore                           0x0000000185bcec98 -[UIApplication _run] + 796
	40  UIKitCore                           0x0000000185bd3064 UIApplicationMain + 124
	41  SwiftUI                             0x00000001d3953aa8 $s7SwiftUI17KitRendererCommon33_ACC2C5639A7D76F611E170E831FCA491LLys5NeverOyXlXpFAESpySpys4Int8VGSgGXEfU_ + 164
	42  SwiftUI                             0x00000001d39537d0 $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 84
	43  SwiftUI                             0x00000001d36e09e0 $s7SwiftUI3AppPAAE4mainyyFZ + 148
	44  LetterTracker.debug.dylib           0x000000010327ef38 $s13LetterTracker0aB3AppV5$mainyyFZ + 40
	45  LetterTracker.debug.dylib           0x000000010327f038 __debug_main_executable_dylib_entry_point + 12
	46  dyld                                0x00000001021e13d8 start_sim + 20
	47  ???                                 0x00000001022aeb4c 0x0 + 4331334476
)
libc++abi: terminating due to uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This UITargetedPreview initializer requires that the view is in a window, but it is not. Either fix that, or use the other initializer that takes a target with an explicit container. (view: <_TtC7SwiftUIP33_64A26C7A8406856A733B1A7B593971F725UIKitIconPreferringButton: 0x14b5167a0> → <_TtGC7SwiftUI16PlatformViewHostGVS_P10$1d4161dcc32PlatformViewRepresentableAdaptorGVS_P10$1d40ff9d418UIKitButtonAdaptorVS_P10$1d40ffb4019PlatformItemContent___: 0x14b518050>)'
terminating due to uncaught exception of type NSException
CoreSimulator 1010.10 - Device: iPhone 16 Pro (048BC4BE-4BFE-4773-8B98-8D3577245BF1) - Runtime: iOS 18.4 (22E238) - DeviceType: iPhone 16 Pro

The view code is as follows:

    /// Section containing the rich text editor for the letter body.
    private var noteSection: some View {
        Section("Letter Body") {
            VStack {
                #if os(macOS)
                RichTextFormat.Toolbar(context: context)
                #endif
                RichTextEditor(text: .constant(NSAttributedString()), context: context)
                    .frame(minHeight: 200)
                    .font(.system(.body, design: .serif))
                    .lineSpacing(5)
                    .overlay(
                        RoundedRectangle(cornerRadius: 8)
                            .stroke(Color.gray.opacity(0.2), lineWidth: 1)
                    )
                    .task {
                        if let attributedString = letter.noteAttributedString {
                            context.setAttributedString(to: attributedString)
                        }
                    }
                #if os(iOS)
                RichTextKeyboardToolbar(
                    context: context,
                    leadingButtons: { $0 },
                    trailingButtons: { $0 },
                    formatSheet: { $0 }
                )
                #endif

            }
            .richTextFormatSheetConfig(.init(colorPickers: colorPickers))
            .richTextFormatSidebarConfig(
                .init(
                    colorPickers: colorPickers,
                    fontPicker: isMac
                )
            )
            .richTextFormatToolbarConfig(.init(colorPickers: []))
        }
    }

The above is called in the main view body:

@Bindable var letter: Letter
    
    /// Environment dismiss action for closing the editor.
    @Environment(\.dismiss) private var dismiss
    
    /// Task for handling letter indexing in Spotlight.
    @State private var indexingTask: Task<Void, Error>?
    
    /// Rich text editing context for the letter content.
    @StateObject private var context = RichTextContext()
    
    /// Store manager for handling subscription status.
    @StateObject private var storeManager = StoreManager.shared
    
    /// Controls the visibility of the subscription view.
    @State private var showingSubscriptionView = false

    var body: some View {
        Form {
            recipientSection
            addressSection
            dateSection
            contentSection
            noteSection
            debugSection
        }
        .navigationTitle(letter.subject?.isEmpty ?? true ? "New Letter" : letter.subject!)
        .toolbar {
            ToolbarItem(placement: .primaryAction) {
                Button("Save", systemImage: "checkmark.circle.fill") {
                    if storeManager.canSaveLetter {
                        saveAndDismiss()
                    } else {
                        showingSubscriptionView = true
                    }
                }
            }
        }
        .sheet(isPresented: $showingSubscriptionView) {
            SubscriptionView()
        }
    }

And LetterEditor Extension:

private extension LetterEditor {

    var isMac: Bool {
        #if os(macOS)
        true
        #else
        false
        #endif
    }

    var colorPickers: [RichTextColor] {
        [.foreground, .background]
    }

    var formatToolbarEdge: VerticalEdge {
        isMac ? .top : .bottom
    }
}
@danielsaidi danielsaidi added the discussion Discussions not yet turned into an action label Apr 8, 2025
@danielsaidi
Copy link
Owner

Thank you @TheApApp. I haven't seen this myself, so it would be great if you could pinpoint the reason for the crash, or if anyone else who also experience it can provide additional information.

@TheApApp
Copy link
Author

TheApApp commented Apr 16, 2025

I will investigate further.. as it seems to be a consistent issue on iPhone and iPad.. It doesn't happen on mac. I am wondering if the difference is due to an attached keyboard? It happens when I select the Aa icon on the bottom of the RichTextEditor view - via touch.

@TheApApp
Copy link
Author

@danielsaidi I am investigating if the issue is the integration I did with SwiftData and displaying the information in AppIntents. Will confirm and close if this proves to be the case.

@TheApApp
Copy link
Author

It appears that my workaround for allowing the NSAttributedString to be used in SwiftData may be the issue, I am using a computed property to allow for editing, while the Data model must store it as Data. in the Editor to address this I am using the approach of

                .task {
                    if let attributedString = letter.noteAttributedString {
                        context.setAttributedString(to: attributedString)
                    }
                }

and the RichTextEditor looks like this

                RichTextEditor(
                    text: .constant(NSAttributedString()),
                    context: context
                ) {
                    $0.textContentInset = CGSize(width: 20, height: 20)
                }

I am wondring if this is the root cause.

@danielsaidi
Copy link
Owner

Perhaps you could try the same in an app that hasn't got all those complexities, to see if that can help clear up the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Discussions not yet turned into an action
Projects
None yet
Development

No branches or pull requests

2 participants