[英]App crashes when using a swiftUI textfield and a WKWebView textfield
我目前有一個應用程序,它使用網站文本字段上方的 SwiftUI 文本字段(比如說搜索框)。 該應用程序不會在 iOS 或 iPadOS 中崩潰。
但是,在 M1 mac 上的 MacCatalyst 中,當我單擊 SwiftUI 文本字段然后單擊網站上的搜索欄時,應用程序會立即崩潰。
我創建了一個附在下面的可重現示例(在 XCode 13.2.1 中運行)
要重現崩潰:
在 Rosetta 上運行時,日志中也會發生崩潰,但應用程序不會終止。
有誰知道問題是什么以及我該如何解決? 先感謝您。
import SwiftUI
import WebKit
struct ContentView: View {
@State var textObject: String = ""
var body: some View {
ZStack {
WebView(url: URL(string: "https://google.com")!)
TextField("", text: $textObject)
.background(
Rectangle()
.foregroundColor(.black)
)
}
}
}
struct WebView: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
}
這是來自 XCode 的錯誤消息: libc++abi: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: <SPRoundedWindow: 0x126774250>. "frame=!CGRectIsNull(frame)"' terminating with uncaught exception of type NSException
libc++abi: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: <SPRoundedWindow: 0x126774250>. "frame=!CGRectIsNull(frame)"' terminating with uncaught exception of type NSException
我的崩潰痕跡:
0 CoreFoundation 0x00000001848001cc __exceptionPreprocess + 240
1 libobjc.A.dylib 0x00000001845517b8 objc_exception_throw + 60
2 Foundation 0x000000018576e840 -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:] + 0
3 AppKit 0x0000000187328f20 -[NSWindow _reallySetFrame:] + 904
4 AppKit 0x00000001873287d8 -[NSWindow _oldPlaceWindow:fromServer:] + 228
5 AppKit 0x00000001873277f8 -[NSWindow _setFrameCommon:display:fromServer:] + 2200
6 SafariPlatformSupport 0x00000001aac63104 __85-[SPSafariPlatformSupport displayOTPAutoFillRelativeToRect:ofView:completionHandler:]_block_invoke + 300
7 SafariPlatformSupport 0x00000001aac62f8c -[SPSafariPlatformSupport displayOTPAutoFillRelativeToRect:ofView:completionHandler:] + 228
8 UIKitCore 0x00000001ac7317a0 -[UIKeyboardImpl generateAutofillCandidateByAddingTask:] + 948
9 UIKitCore 0x00000001ac73b8d0 -[UIKeyboardImpl setDelegate:force:] + 6248
10 UIKitCore 0x00000001ac41fad4 -[UIKeyboardSceneDelegate _reloadInputViewsForKeyWindowSceneResponder:] + 2080
11 UIKitCore 0x00000001ac41f288 -[UIKeyboardSceneDelegate _reloadInputViewsForResponder:] + 164
12 UIKitCore 0x00000001abd918a0 -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] + 132
13 UIKitCore 0x00000001abd3a298 -[UIResponder becomeFirstResponder] + 856
14 UIKit 0x0000000202830aa4 -[UITextInputUIResponderAccessibility becomeFirstResponder] + 52
15 UIKitCore 0x00000001abd6a100 -[UIView(Hierarchy) becomeFirstResponder] + 176
16 WebKit 0x00000001bd66c5c0 -[WKContentView(WKInteraction) becomeFirstResponderForWebView] + 152
17 WebKit 0x00000001bd246768 -[WKWebView(WKViewInternalIOS) becomeFirstResponder] + 148
18 WebKit 0x00000001bd67f88c -[WKContentView(WKInteraction) _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:] + 1840
19 WebKit 0x00000001bd381ea0 _ZN6WebKit12WebPageProxy15elementDidFocusERKNS_25FocusedElementInformationEbbN3***9OptionSetIN7WebCore13ActivityState4FlagEEERKNS_8UserDataE + 216
20 WebKit 0x00000001bd5f66b8 _ZN6WebKit12WebPageProxy17didReceiveMessageERN3IPC10ConnectionERNS1_7DecoderE + 61472
21 WebKit 0x00000001bcfcc5cc _ZN3IPC18MessageReceiverMap15dispatchMessageERNS_10ConnectionERNS_7DecoderE + 272
22 WebKit 0x00000001bd35a284 _ZN6WebKit15WebProcessProxy17didReceiveMessageERN3IPC10ConnectionERNS1_7DecoderE + 40
23 WebKit 0x00000001bcfaeb4c _ZN3IPC10Connection15dispatchMessageENSt3__110unique_ptrINS_7DecoderENS1_14default_deleteIS3_EEEE + 808
24 WebKit 0x00000001bcfae15c _ZN3IPC10Connection24dispatchIncomingMessagesEv + 508
25 JavaScriptCore 0x00000001bc5278d0 _ZN3***7RunLoop11performWorkEv + 292
26 JavaScriptCore 0x00000001bc528a40 _ZN3***7RunLoop11performWorkEPv + 36
27 CoreFoundation 0x0000000184780c5c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
28 CoreFoundation 0x0000000184780ba8 __CFRunLoopDoSource0 + 208
29 CoreFoundation 0x0000000184780894 __CFRunLoopDoSources0 + 268
30 CoreFoundation 0x000000018477f208 __CFRunLoopRun + 820
31 CoreFoundation 0x000000018477e734 CFRunLoopRunSpecific + 600
32 HIToolbox 0x000000018d310f68 RunCurrentEventLoopInMode + 292
33 HIToolbox 0x000000018d310cdc ReceiveNextEventCommon + 552
34 HIToolbox 0x000000018d310a9c _BlockUntilNextEventMatchingListInModeWithFilter + 72
35 AppKit 0x00000001872d4ce0 _DPSNextEvent + 844
36 AppKit 0x00000001872d3584 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1332
37 AppKit 0x00000001872c55a4 -[NSApplication run] + 596
38 AppKit 0x0000000187296c78 NSApplicationMain + 1064
39 AppKit 0x000000018756d084 +[NSWindow _savedFrameFromString:] + 0
40 UIKitMacHelper 0x0000000199c7d9ac UINSApplicationMain + 1280
41 UIKitCore 0x00000001abc0ab28 UIApplicationMain + 164
42 SwiftUI 0x00000001c0fce8b0 $s7SwiftUI17KitRendererCommon33_ACC2C5639A7D76F611E170E831FCA491LLys5NeverOyXlXpFAESpySpys4Int8VGSgGXEfU_ + 164
43 SwiftUI 0x00000001c0fce808 $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 252
44 SwiftUI 0x00000001c08f54cc $s7SwiftUI3AppPAAE4mainyyFZ + 128
45 TestingGround 0x000000010056d634 $s13TestingGround0aB3AppV5$mainyyFZ + 40
46 TestingGround 0x000000010056d6d4 main + 12
47 dyld 0x00000001015a50f4 start + 520
我不確定這里的違規者是什么,可能是 MacCatalyst 本身,但答案實際上是在文本字段上禁用自動更正。
原因是因為運行 MacCatalyst 應用程序假定有一個帶有 TextField 的虛擬鍵盤,因此此類錯誤經常出現在生產代碼中。 出於某種原因,這會導致 M1 設備崩潰。 禁用預測文本是解決此問題的方法。 這是代碼:
import SwiftUI
import WebKit
struct ContentView: View {
@State var textObject: String = ""
var body: some View {
ZStack {
WebView(url: URL(string: "https://google.com")!)
TextField("", text: $textObject)
.background(
Rectangle()
.foregroundColor(.black)
)
.disableAutoCorrection(true)
}
}
}
struct WebView: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
}
我通過調配私有方法-[NSWindow _reallySetFrame:]
並手動更正錯誤輸入來解決此崩潰問題。 到目前為止,我還沒有發現這種調酒的任何副作用。
@objc private extension NSWindow {
func kjy_swizzle_reallySetFrame(_ frame: CGRect) {
var frame = frame
if frame.isNull {
frame = .zero
}
kjy_swizzle_reallySetFrame(frame)
}
}
注意:這不是解決方法的完整源代碼(您需要添加代碼來調配私有NSWindow
方法)。 如果您不熟悉“method swizzling”,請在互聯網上搜索。
我在使用 maccatalyst 的 WKWebView 的 swift 中也遇到了同樣的崩潰。 最后嘗試了不同的解決方案后,我添加了這段代碼來修復我的崩潰。
typealias winClosureType = @convention(c) (Any, Selector) -> UITextAutocorrectionType
func swizzleInputTraits() {
guard let textInputTraits: AnyClass = NSClassFromString("UITextInputTraits") else { return }
let sel_AutocorrectionType: Selector = sel_getUid("autocorrectionType")
if let method = class_getInstanceMethod(textInputTraits, sel_AutocorrectionType) {
let originalImp: IMP = method_getImplementation(method)
let original: winClosureType = unsafeBitCast(originalImp, to: winClosureType.self)
let block : @convention(block) (Any) -> UITextAutocorrectionType = { (textInputTraits) in
let obj = original(textInputTraits, sel_AutocorrectionType)
return obj == .default ? .no : obj
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}
}
在這里,我正在調整 UITextInputTraits 的 autocorrectionType 屬性。 我默認為所有文本字段禁用自動更正類型。 如果任何文本字段需要,我們必須顯式啟用 autocorrectionType 屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.