Plugin for webview issue


#1

I’m using a plugin to create a view with links embedded in the text. So when you tap the item, it calls an event that is in the code behind. It works great on Android, ios simulator, but doesn’t work in ios on the device. It feels to me like it is some permission error that does not allow javascript to run in the webview on the device. Does anyone have any idea if this would be the case?

Plugin: https://github.com/shripalsoni04/nativescript-webview-interface

What I’m trying to build:

09%20PM

06%20PM


#2

Is this happening only on iOS device? Would you mind sharing some code to understand what exactly you are trying?


#3

Sure, thanks for asking:

This is an angular implementation. In the component template.

<web-view id="wv" #wv></web-view>

In the code behind it populates the webview then runs some code to the webview javascript:

@ViewChild('wv') webView: ElementRef;

private setupWebViewInterface() {
    //   console.log("setup web views");
    let webView: WebView = this.webView.nativeElement;
    this.oVocabWebViewInterface = new webViewInterfaceModule.WebViewInterface(webView, '~/www/index.html');

    // load of webView.
    webView.on(WebView.loadFinishedEvent, (args: LoadEventData) => {
        console.log("webview loaded");
      if (!args.error) {
        this.loadVocabInWebView();
        setTimeout(()=>{
            this.getWebviewHeight();
        }, 300);
      }
      else {
          console.error(args.error);
      }
    });

private loadVocabInWebView() {
    this.oVocabWebViewInterface.emit('loadBody', this.lessonDetail.body_text);
}

private getWebviewHeight() {
    this.oVocabWebViewInterface.emit('needheight');
}

listenVocabWebViewEvents(){  
    // let iwv = <WebView>this.instructionWebView.nativeElement;
    // handles language selectionChange event.
    this.oVocabWebViewInterface.on('vocabTapped', (vocabid) => {
        //console.log("vocab tapped");
        this.playerService.openVocabModal(vocabid);
    });

    this.iVocabWebViewInterface.on('vocabTapped', (vocabid) => {
        //console.log("vocab tapped");
        this.playerService.openVocabModal(vocabid);
    });

    this.iVocabWebViewInterface.on('divheight', (h) => {
        let startHeight = this.wv1wrapper.nativeElement.height ? this.wv1wrapper.nativeElement.height : 1;
        let nh = h+26
        console.log("in divheight event: " + h);
        this.playerService.changeHeight(this.wv1wrapper.nativeElement, this.animationService.toTheFifth, 300, startHeight, nh);

    });

In the webview javascript:

(function () {
    var oWebViewInterface = window.nsWebViewInterface;


    function sendSelectedValue(vocabid){
        oWebViewInterface.emit('vocabTapped', vocabid);
    }

    function sendDivHeight(){
        let root = document.getElementById('body');
        let calcHeight = root.clientHeight;
        oWebViewInterface.emit('divheight', calcHeight);
    }

    function addNativeMsgListener() {
        oWebViewInterface.on('loadBody', function (body_text) {
            console.log('add body_text');
            addBodyHtml(body_text);
        });
        oWebViewInterface.on('needheight', sendDivHeight);
        oWebViewInterface.on('removeBody', function () {
            console.log('remove body_text');
            removeBodyHtml();
        });
    }

    function addBodyHtml(body_text){
        let root = document.getElementById('body');
        while (root.firstChild) root.removeChild(root.firstChild);
        let bodydiv = document.createElement('div');
        bodydiv.addEventListener('click', handleEvent, false);
        bodydiv.innerHTML = body_text;
        root.appendChild(bodydiv);
    }

    function removeBodyHtml(){
        let root = document.getElementById('body');
        while (root.firstChild) root.removeChild(root.firstChild);
    }

    function handleEvent(event) {
        if (event.target.tagName.toLowerCase() === 'a') {
            sendSelectedValue(event.target.id);
            }
    }
    
    /**
     * Defines global functions which will be called from andorid/ios
     */
    // function defineNativeInterfaceFunctions(){
    // }
    
    function init() {
        
        addNativeMsgListener();

    }

    init();

    
    
})();


Yes, it works in Android, on the deivce as well as in the emulator. It works in my ios Simulator but not directly on the ios device. I get an error. Error Domain=WKErrorDomain Code=4 “A JavaScript exception occurred”


#4

Can you share the HTML too, so I may able to try running test on my end.


#5

Yes. Thanks

<!doctype html>
<head>
    <style>
        a {
            color: #2571BD;
            font-weight: bold;
        }
        div.body {
            min-height: 300px;
        }
    </style>
</head>
<html>
    <body>
        <div id="body"></div>
        <script src="./lib/es6-promise.min.js"></script>
        <script src="./lib/nativescript-webview-interface.js"></script>
        <script src="./index.js"></script>
    </body>
</html>

Here is some sample data getting appended to the webview:

"Grinding can be performed on a variety of different surfaces for both shaping and <a id='26442'>finishing</a> parts. It may be used to remove excess material from a part, to form intricate shapes, or to fit parts with specific <a id='26439'>dimensions</a>. Grinding can produce a part with very tight <a id='26437'>tolerances</a> and fine surface finish.

In ngOnInit this can be called:

this.setupWebViewInterface();

#6

On ios I do get the event webview loaded but then it doesn’t process the next event of setting the height.


#7

With given pices of code I couldn’t reproduce the exact issue you are facing. If possible I would ask you to create a playground example to debug this further.


#8

Thanks for your willingness to help. I have setup a playground, but am having trouble getting the web-view to load. I’m not getting errors, nor am I getting the Webview. could you take a look?


#9

I found you had to make a reference to the (this) context because (this) was undefined on the callback.

Setup the events in ngAfterViewInit and reference it here.

ngAfterViewInit() {
		let webView: WebView = this.webView.nativeElement;
		this.oVocabWebViewInterface = new webViewInterfaceModule.WebViewInterface(webView);
        let context = this;

        //Then your code

        // load of webView.
		webView.on(WebView.loadFinishedEvent, (args: LoadEventData) => {
			console.log("webview loaded");
		  if (!args.error) {
			context.loadVocabInWebView();
			setTimeout(()=>{
				context.getWebviewHeight();
			}, 300);
		  }
		  else {
			  console.error(args.error);
		  }
		});
	

#10

Also your webview needs to be wrapped in a gridview or iOS sizing is jacked.


#11

Thanks, but I’m still not getting a webview with content. Have you been able to fix up my playground and see a webview?


#12

Yep, done. Your src to the html was not using the sub path of home.

I also made some other changes to help wire up the events right.


#13

can you send me the link to the playground you created?


#14

Ah, ok, I found it, just took off the version and found it.

@manojdcoder now, this does demonstrate the error on ios. I get this error:

[bradrice’s iPhone 6-64]: ERROR: Unhandled Promise rejection: Error Domain=WKErrorDomain Code=4 “A JavaScript exception occurred” UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating ‘window.nsWebViewInterface._onNativeEvent’), WKJavaScriptExceptionColumnNumber=26, WKJavaScriptExceptionSourceURL=file:////var/mobile/Containers/Data/Application/F4DD5482-3700-441E-8D68-7844C7C8993D/Documents/Playground/LiveSync/app/home/www/index.html, NSLocalizedDescription=A JavaScript exception occurred} ; Zone: ; Task: null ; Value: Error Domain=WKErrorDomain Code=4 “A JavaScript exception occurred” UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating ‘window.nsWebViewInterface._onNativeEvent’), WKJavaScriptExceptionColumnNumber=26, WKJavaScriptExceptionSourceURL=file:////var/mobile/Containers/Data/Application/F4DD5482-3700-441E-8D68-7844C7C8993D/Documents/Playground/LiveSync/app/home/www/index.html, NSLocalizedDescription=A JavaScript exception occurred} undefined

Here is the playground: [bradrice’s iPhone 6-64]: ERROR: Unhandled Promise rejection: Error Domain=WKErrorDomain Code=4 “A JavaScript exception occurred” UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating ‘window.nsWebViewInterface._onNativeEvent’), WKJavaScriptExceptionColumnNumber=26, WKJavaScriptExceptionSourceURL=file:////var/mobile/Containers/Data/Application/F4DD5482-3700-441E-8D68-7844C7C8993D/Documents/Playground/LiveSync/app/home/www/index.html, NSLocalizedDescription=A JavaScript exception occurred} ; Zone: ; Task: null ; Value: Error Domain=WKErrorDomain Code=4 “A JavaScript exception occurred” UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating ‘window.nsWebViewInterface._onNativeEvent’), WKJavaScriptExceptionColumnNumber=26, WKJavaScriptExceptionSourceURL=file:////var/mobile/Containers/Data/Application/F4DD5482-3700-441E-8D68-7844C7C8993D/Documents/Playground/LiveSync/app/home/www/index.html, NSLocalizedDescription=A JavaScript exception occurred} undefined


Playground on ios simulator