NSInvalidArgumentException:当脚本消息处理程序已经存在时,如何检查名称的脚本消息处理程序?

NSInvalidArgumentException: How to check script message handler with name when one already exists?

每当 View 切换到另一个 View 时,错误提示它正在添加名称为 "jsHandler" 的脚本消息处理程序,而该处理程序已经存在?我是否必须检查现有名称然后添加它?我该如何检查?我在文档中找不到任何内容。我也尝试使用 ModalView。

这里是 ContentView

struct ContentView: View {
    @State var counter: Int = 0

    var body: some View {
        NavigationView{
            WebViewController(filePath: "index.html")
            .navigationBarTitle(Text("Title"))
            .navigationBarItems(trailing:
                NavigationLink(destination: Text("Another View")) {
                    Text("Next")
                }
            )
        }
    }
}

这是 WebViewController。

import SwiftUI
import WebKit

struct WebViewController: UIViewRepresentable {

    let filePath: String

    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {

        uiView.configuration.userContentController.add(ContentController(), name: "jsHandler")

        let bundleURL = Bundle.main.resourceURL!.absoluteURL
        let html = bundleURL.appendingPathComponent(filePath)
        uiView.loadFileURL(html, allowingReadAccessTo:bundleURL)
    }
    class ContentController: NSObject, WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "jsHandler"{
                print(message.body)
            }
        }
    }
}

这里是Logcat:

    2019-11-16 23:45:41.330209+0630 tut1[33510:959393] Simulator user has requested new graphics quality: 10
2019-11-16 23:45:46.236890+0630 tut1[33510:959393] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to add script message handler with name 'jsHandler' when one already exists.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff23baa1ee __exceptionPreprocess + 350
    1   libobjc.A.dylib                     0x00007fff50864b20 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff23baa02c +[NSException raise:format:] + 188
    3   WebKit                              0x00007fff2d0c49dd -[WKUserContentController addScriptMessageHandler:name:] + 209
    4   tut1                                0x000000010c36d613 $s4tut117WebViewControllerV12updateUIView_7contextySo05WKWebC0C_7SwiftUI0F20RepresentableContextVyACGtF + 483
    5   tut1                                0x000000010c36de91 $s4tut117WebViewControllerV7SwiftUI19UIViewRepresentableAadEP06updateG0_7contexty0G4TypeQz_AD0gH7ContextVyxGtFTW + 17
    6   SwiftUI                             0x00007fff2c5fc341 $s7SwiftUI32PlatformViewRepresentableAdaptor33_19642D833A8FE469B137699ED1426762LLV06updateD8Provider_7contexty10UIViewTypeQz_AA0cdE7ContextVyADyxGGtF + 289
    7   SwiftUI                             0x00007fff2c2653a7 $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLV6update7contexty14AttributeGraph0O7ContextVyADyxGGz_tFyyXEfU_ + 2343
    8   SwiftUI                             0x00007fff2c25eb86 $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLV6update7contexty14AttributeGraph0O7ContextVyADyxGGz_tF + 310
    9   SwiftUI                             0x00007fff2c2665d0 $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLVyxG14AttributeGraph07UntypedM0AafGP7_update_5graph9attributeySv_So10AGGraphRefaSo11AGAttributeatFZTW + 32
    10  AttributeGraph                      0x00007fff2f8f1849 $sTA + 25
    11  AttributeGraph                      0x00007fff2f8d9255 _ZN2AG5Graph11UpdateStack6updateEv + 1111
    12  AttributeGraph                      0x00007fff2f8d9513 _ZN2AG5Graph16update_attributeEjb + 377
    13  AttributeGraph                      0x00007fff2f8de131 _ZN2AG8Subgraph6updateEj + 929
    14  SwiftUI                             0x00007fff2c10d100 $s7SwiftUI9ViewGraphC14runTransaction33_D63C4EB7F2B205694B6515509E76E98BLL2inySo10AGGraphRefa_tF + 224
    15  SwiftUI                             0x00007fff2c10d517 $s7SwiftUI9ViewGraphC13updateOutputs2atyAA4TimeV_tFSb5prefs_Sb9idealSizeAC0F0V7outputstSo10AGGraphRefaXEfU_ + 103
    16  SwiftUI                             0x00007fff2c10d1d1 $s7SwiftUI9ViewGraphC13updateOutputs2atyAA4TimeV_tF + 145
    17  SwiftUI                             0x00007fff2c4af579 $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtFyyXEfU_yyXEfU_ + 1001
    18  SwiftUI                             0x00007fff2c4aef8a $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtFyyXEfU_ + 634
    19  SwiftUI                             0x00007fff2c4a4274 $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtF + 436
    20  SwiftUI                             0x00007fff2c65a182 $s7SwiftUI14_UIHostingViewC14layoutSubviewsyyF + 226
    21  SwiftUI                             0x00007fff2c65a1a5 $s7SwiftUI14_UIHostingViewC14layoutSubviewsyyFTo + 21
    22  UIKitCore                           0x00007fff47a52ad5 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
    23  QuartzCore                          0x00007fff2b06e91d -[CALayer layoutSublayers] + 255
    24  QuartzCore                          0x00007fff2b073323 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 517
    25  QuartzCore                          0x00007fff2b07fa7c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
    26  QuartzCore                          0x00007fff2afc6e54 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
    27  QuartzCore                          0x00007fff2affc32f _ZN2CA11Transaction6commitEv + 643
    28  SwiftUI                             0x00007fff2c65a2a4 $s7SwiftUI14_UIHostingViewC16displayLinkTimer9timestampyAA4TimeV_tF + 228
    29  SwiftUI                             0x00007fff2c00af7d $s7SwiftUI11DisplayLinkC07displayD5Timer33_D912470A6161D66810B373079EE9F26ALLyySo09CADisplayD0CF + 77
    30  SwiftUI                             0x00007fff2c00afd6 $s7SwiftUI11DisplayLinkC07displayD5Timer33_D912470A6161D66810B373079EE9F26ALLyySo09CADisplayD0CFTo + 38
    31  QuartzCore                          0x00007fff2af27b66 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 640
    32  QuartzCore                          0x00007fff2b000ac3 _ZL22display_timer_callbackP12__CFMachPortPvlS1_ + 299
    33  CoreFoundation                      0x00007fff23acde8d __CFMachPortPerform + 157
    34  CoreFoundation                      0x00007fff23b0d9c9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    35  CoreFoundation                      0x00007fff23b0d028 __CFRunLoopDoSource1 + 472
    36  CoreFoundation                      0x00007fff23b07b64 __CFRunLoopRun + 2516
    37  CoreFoundation                      0x00007fff23b06e66 CFRunLoopRunSpecific + 438
    38  GraphicsServices                    0x00007fff38346bb0 GSEventRunModal + 65
    39  UIKitCore                           0x00007fff47578dd0 UIApplicationMain + 1621
    40  tut1                                0x000000010c36cc3b main + 75
    41  libdyld.dylib                       0x00007fff516ecd29 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

我以前没有使用过 SwiftUI,但我猜你在 updateUI 中执行的操作应该只发生一次,而不是需要在 makeUIView 期间完成:

import SwiftUI
import WebKit

struct WebViewController: UIViewRepresentable {

    let filePath: String

    func makeUIView(context: Context) -> WKWebView  {
        let uiView = WKWebView()
        uiView.configuration.userContentController.add(ContentController(), name: "jsHandler")

        let bundleURL = Bundle.main.resourceURL!.absoluteURL
        let html = bundleURL.appendingPathComponent(filePath)
        uiView.loadFileURL(html, allowingReadAccessTo:bundleURL)

        return uiView
    }

    class ContentController: NSObject, WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "jsHandler"{
                print(message.body)
            }
        }
    }
}