ShawnFoo / SwiftWebViewBridge

Swift version of WebViewJavascriptBridge with more simplified and friendly methods to handle messages between Swift and JS in UIWebViews
MIT License
137 stars 34 forks source link

Bridge stops receiving messages after call is cancelled/fails #19

Open steventnorris-40AU opened 7 years ago

steventnorris-40AU commented 7 years ago

If you get a loading failure, calling didFailLoadWithError on your delegate, the bridge no longer receives or responds to any JS messages passed, as if the bridge connection is severed. In my case, I reload links into the same web view, so after a single failure, no subsequent loads handle JS messages.

steventnorris-40AU commented 7 years ago

Further investigation:

If you instantiate the bridge and reconnect it to the webview on failure, you can get the bridge working again, but of course that's because I reconnect a new bridge.

In addition, if you declare a delegate after the bridge, the bridge does not work.

I use an "initializeBridge" method on init of the view. I then call that method again on my delegate's "didFailLoadWithError". This is a workaround, but does not seem to be intended functionality.

EX:

This works:

private func initializeBridge() {
        self.delegate = self

        bridge = SwiftWebViewBridge.bridge(self, defaultHandler: { _ , _ in print("DEFAULT") })
        bridge.registerHandlerForJS(handlerName: "shotPlaced") { jsonData, responseCallback in
            guard let jsonDict = jsonData as? [Double] else {
                print("SHOT PLACED")
                self.onShotPlaced?(.error)
                return
            }

            let pos: FloorPosition = (jsonDict[0], jsonDict[1])
            self.onShotPlaced?(.success(pos))
        }
        bridge.registerHandlerForJS(handlerName: "courtLoaded") { jsonData, responseCallback in
            print("JS MESSAGE")
            self.loadingIndicator.stopAnimating()
        }
    }

This does not:

private func initializeBridge() {
        bridge = SwiftWebViewBridge.bridge(self, defaultHandler: { _ , _ in print("DEFAULT") })
        bridge.registerHandlerForJS(handlerName: "shotPlaced") { jsonData, responseCallback in
            guard let jsonDict = jsonData as? [Double] else {
                print("SHOT PLACED")
                self.onShotPlaced?(.error)
                return
            }

            let pos: FloorPosition = (jsonDict[0], jsonDict[1])
            self.onShotPlaced?(.success(pos))
        }
        bridge.registerHandlerForJS(handlerName: "courtLoaded") { jsonData, responseCallback in
            print("JS MESSAGE")
            self.loadingIndicator.stopAnimating()
        }

        self.delegate = self
    }