iOS8 UIWebView JavaScript Interface

Problem

In iOS8, UIWebView javascript interface doesn’t work some cases.
(iOS7, iOS9 works correctly. Only iOS8 has this problem)
I have no idea that it doesn’t work.
“doesn’t work” mean that we cannot catch event shouldStartLoadWithRequest when running URL schema

Example

This is simple example works
ViewController.swift

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {

    private var webView : UIWebView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.webView = UIWebView()
        
        self.view.addSubview(self.webView!)
        
        //self.webView?.loadRequest(NSURLRequest(URL: NSURL(string: "https://www.google.co.jp")!))
        
        let path = NSBundle.mainBundle().pathForResource("index", ofType: "html")!
        let url = NSURL(string: path)!
        self.webView?.delegate = self
        self.webView?.loadRequest(NSURLRequest(URL:url))
    }

    override func viewWillLayoutSubviews() {
        let frame : CGRect  = self.view.frame
        self.webView?.frame = CGRectMake(0, 0, frame.width, frame.height)
    }
    
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        
        NSLog("Come");
        
        return true
    }
}

index.html

<html>
    <head>
        <title>Test</title>
        <script>
            
        function myFunction() {
            location.href = "native-app://test";
         }
        
        </script>
    </head>
    <body>
        <h3>Hello World!</h3>
        <button onclick="myFunction()">Click me</button>
    </body>
</html>

The point is location.href
This case will work.
“native-app://test” this doesn’t have any arguments after test
Let’s try other cases

location.href = "native-app://test";  // works
location.href = "native-app://test:10";  // works
location.href = "native-app://test:true";  // doesn't work
location.href = "native-app://test:japan";  // doesn't work

No arguments and number argument work. Text argument doesn’t work

Solution

Use temporary iframe use following code in myFunction()

var iframe = document.createElement("iframe");
iframe.setAttribute("src", "native-app://test:japan");
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null

To use this, we can catch the event.

Ref : stackoverflow