IOS 8.3 UIWebView JavaScript for native communication is broken

EDIT: the solution was to return NO from the delegate method webView:shouldStartLoadWithRequest:navigationType:when it received a JavaScript message, this allowed everything in all versions.

JavaScript behavior on native (Obj-C or Swift) communication inside UIWebViewhas changed in iOS 8.3.

Let's say I want to send a couple of messages from JS to native code 1 :

window.open('myurlscheme://webview?message=1');
window.open('myurlscheme://webview?message=2');
window.open('myurlscheme://webview?message=3');
window.open('myurlscheme://webview?message=4');

I use this delegate method to catch messages in native code:

- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
    if ([inRequest.URL.scheme isEqualToString:@"myurlscheme"]) {
        NSLog(@"%@", inRequest.URL.absoluteString);
    }

    return YES;
}

And I get the following in the Xcode console:

15:19:56.387 TestJSObjCComms[55731:766108] myurlscheme://webview?meaning=0
15:19:56.404 TestJSObjCComms[55731:766108] myurlscheme://webview?meaning=1
16:20:06.300 TestJSObjCComms[57967:819448] void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
15:20:06.407 TestJSObjCComms[55731:766108] myurlscheme://webview?meaning=2
15:20:16.409 TestJSObjCComms[55731:766108] myurlscheme://webview?meaning=3
15:20:26.411 TestJSObjCComms[55731:766108] myurlscheme://webview?meaning=4

. , 10 . 30 , , ! , ( ) 10 , .

, UIWebView iOS 8.3, . , UIWebView JavaScript 10 . , JavaScript - , , .

, , , window.open(myURL) , window.location = myURL, , , , , .

1 window.open(myURL) window.location = myURL, (. 1 ).

1 . setTimeout "". , 3 iOS 8.3, 8.1 7.0, setTimeout ​​50 .

var buffer = [];
function doRequest(url) {
    buffer.push(url);
    if (buffer.length === 1) {
        window.location = url;
    }
}

function resolveRequest(request) {
    var index = buffer.indexOf(request);
    if (index != -1) {
        buffer.splice(index, 1);
    }
    if (buffer.length) {
        setTimeout(function() {
            window.location = buffer[0];
        }, 50);
    }
}

, . - .

1: UIWebView JavaScript ↔ .

-

1) window.location = myURL ( window.location.href = myURL, window.location.replace(myURL) ..).

2) window.open(myURL) window.open(myURL, ‘_blank’) src: <iframe>, <embed>. , : <audio>, <video>, <script>, <style>.

3) , . , UIWebView webView:shouldStartLoadWithRequest:navigationType:.

JavaScript:

var buffer = [];
function doRequest(url) {
    buffer.push(url);
    if (buffer.length === 1) {
        window.location = url;
    }
}

function resolveRequest(request) {
    var index = buffer.indexOf(request);
    if (index != -1) {
        buffer.splice(index, 1);
    }
    if (buffer.length) {
        window.location = buffer[0];
    }
}

Obj-C:

- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
    if ([inRequest.URL.scheme isEqualToString:@"myurlscheme"]) {
        NSString *javaScript = [NSString stringWithFormat:@"resolveRequest('%@')", inRequest.URL.absoluteString];
        [self.webView stringByEvaluatingJavaScriptFromString:javaScript];
        NSLog(@"%@", inRequest.URL.absoluteString);
    }

    return YES;
}

( iPhone 5 Simulator)

iOS 7.1

1: .

2: ( ).

3: ( ).

iOS 8.1

1: , iOS 7.1

2: , 10 ( , ).

3: , iOS 7.1

iOS 8.3

1: , iOS 7.1

2: , iOS 8.1

3: , 10 ( , ).

+4

All Articles