Skip to content

fix(ios): stop reading the pasteboard in text input canPerformAction - #132

Merged
huhuanming merged 4 commits into
mainfrom
fix/ios-paste-hang
Sep 24, 2026
Merged

huhuanming merged 4 commits into
mainfrom
fix/ios-paste-hang

Conversation

@huhuanming

Copy link
Copy Markdown
Contributor

Summary

Fixes an iOS 27 main-thread hang in @onekeyfe/react-native-text-input that the watchdog turns into a kill (Sentry REACT-NATIVE-4Y1, "Fatal App Hang Fully Blocked", iPhone17,1 / iOS 27.0 24A437, app 6.6.0 build 2026091844).

Same change as #131 (which targets hotfix/3.0.154 for app-monorepo release/v6.6.0), applied to main so the next regular release carries it.

Root cause

The RCTUITextField(OneKeyPaste) / RCTUITextView(OneKeyPaste) swizzle of canPerformAction:withSender: read UIPasteboard.generalPasteboard.hasImages, which is a synchronous XPC call to pasteboardd. On iOS 27, UIIntelligenceSupport validates UICommands from a run-loop block with no user action, so this runs on the main thread in the background:

UIIntelligenceSupport (CFRunLoop block)
  -[UICommand _resolvedTargetFromFirstTarget:sender:]
    _UIResponderCanPerformAction
      -[RCTUITextField(OneKeyPaste) onekey_canPerformAction:withSender:]
        +[_UIConcretePasteboard _pasteboardNamed:createIfNotFound:]
          -[PBServerConnection pasteboardWithName:...]
            xpc_connection_send_message_with_reply_sync   <- blocked >= 5 s

Fix

  • onekey_canPerformAction: reads a cached std::atomic<bool> instead of touching UIPasteboard.
  • A serial background queue refreshes the cache on UIPasteboardChangedNotification, UIApplicationDidBecomeActiveNotification, and text field / text view begin-editing. Refresh requests that arrive while one is queued are merged into it.
  • The paste path (onekey_paste:) is unchanged; it still reads the pasteboard only when the user actually pastes.

Tradeoff: right after returning from another app with a copied image, the Paste menu item may miss the image for the moment the async refresh takes. Text paste is unaffected (it falls through to UIKit).

Test plan

  • clang++ -fsyntax-only against the iOS 27.0 SDK and the app's React headers: no errors or warnings
  • iOS 27 device: long-press a text input with an image on the pasteboard, then Paste works and the image paste event fires
  • iOS 27 device: copy an image in Photos, return to the app, then paste into a text input
  • iOS 26 device: text and image paste unchanged

🤖 Generated with Claude Code

iOS 27 validates UICommands from UIIntelligenceSupport without any user
action, which calls canPerformAction: on the focused RCTUITextField. The
OneKeyPaste swizzle read UIPasteboard.generalPasteboard.hasImages there,
a synchronous XPC call to pasteboardd, and a slow reply blocked the main
thread until the watchdog killed the app (Sentry REACT-NATIVE-4Y1,
"Fatal App Hang Fully Blocked", iOS 27.0).

canPerformAction: now reads a cached flag. A background serial queue
refreshes it on UIPasteboardChangedNotification, app activation and text
input begin-editing, coalescing concurrent refresh requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread native-views/react-native-text-input/ios/OneKeyTextInputPasteObserver.mm Outdated
@huhuanming
huhuanming merged commit 9db1814 into main Sep 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants