0

Have an interesting issue and I couldn't find any related answers. I can't be too descriptive on code due to security policies at the company, but I will provide an outline of the flow and some generic code.

Scenario:

  • Native swift application with menus and a WKWebView loading a SPA page on angular 15 and ui-router.
  • The initial load url is the full url without any hashes, say https://server.com/path/index.html?flag=value
  • The site loads, receives some config data from server, sets itself up, and navigates to default state finishing at on https://server.com/path/index.html?flag=value#/page/main
  • Site sends configuration data to app via postMessage interface (window.webkit.messageHandlers.webViewEvent.postMessage())
  • Native app receives data and builds flyout menus with full url paths, like https://server.com/path/index.html?flag=value#page/blah.
  • ISSUE 1: User clicks on flyout menu and the site does the work but when it tries to send a msg via postMessage to the app it is never received. There are no logs of any kind, the listener is never triggered, although being the same interface that received the config data previously. The experience for the user is as if there was no action performed. We cant find any errors on console log as well.
  • ISSUE 2: If User clicks again on same flyout menu the site does a full reload which is a problem since its a SPA. The site retriggers all the config data but finally the message is sent to the app.

Another interesting fact is that it works perfectly on android, and also works perfectly on iOS WHEN testing on a lower dev environment.

I know this is too generic but please let me know if you have any ideas of what this could be. I can also share more specific code editing this question.

found:

None of them gave me hints of what to look for

Code that sends:

callback = (messageToPost: WebViewMessage): void => {  
   this.browserWindow?.webkit?.messageHandlers?.webViewEvent?.postMessage(messageToPost);
};
callback(JSON.stringify(message));
    

Code that receives on mobile:

func didReceiveWKScriptMessage(_ message: WKScriptMessage, url: URL?) {
    if message.name == WKWebViewConfiguration.ScriptName.jsWebViewEvent,
                let baseResponse: BaseMessageEventResponse = message.decode() {
        switch baseResponse.messageType {
        
        case .the_message:
            if let messageResponse: TheType = message.decode(),
               // never reaches here the first time
            }

and

extension WebBrokerWebViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {        
    viewModel.inputs.didReceiveWKScriptMessage(message, url: message.webView?.url)
}

}

silvio
  • 5,651
  • 2
  • 17
  • 14

1 Answers1

0

I found the answer so I'm closing this question.

Turns out that our responsive site had an analytics iframe being injected on higher environments and once the iframe loaded the reference to the JS interface , which was set by native to allow us to post messages on the window object , became null. It was not an error on any of the side but a side-effect of the iframe loading.

This seems to be a bug on the WKWebView interface and I'm following up with the appropriate team for alternatives. Will close the question for now.

silvio
  • 5,651
  • 2
  • 17
  • 14