Note this is not a duplicate due to the "in iOS 7" part of my question and the fact previous behavior (and thus answers to previous questions) has changed.
I want to know how JavaScript code invoked via a UIWebView can invoke Objective-C code in iOS 7. This is something I have previously used extensively in projects in the past, however the behavior on iOS 7 has changed with the result that the webView delegate's didFailLoadWithError gets called when previously it did not.
I used to invoke Objective-C functionality using the custom url trick:
function invokeObjectiveC(action, target, data) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "MY-URLScheme:" + action + ":" + target + ":" + data);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
The particular line that causes didFailLoadWithError: to get called is this one:
document.documentElement.appendChild(iframe);
The other common alternative approach sprinked around the internet to do the same thing is this:
window.location = "MY-URLScheme:" + action + ":" + target + ":" + data;
And this works on iOS 7 in that didFailLoadWithError does not get called, however it has a (known) problem that if its called twice quickly in succession the first call is lost.
So I wondered how Cordova is doing this, so I downloaded source code and had a look and I think they are doing it similar to me like this (the 3rd line is different) :
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "MY-URLScheme:" + action + ":" + target + ":" + data);
document.body.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
However that still results in didFailLoadWithError getting called. Which has left me puzzled as to why Cordova hasn't done anything to rectify this (assuming I'm looking at their code correctly).
The fact that didFailLoadWithError gets called does not seem to be detremental as pages still load and the Objective-C still gets invoked. However it is very very unsatisfactory to have code that results in an error method getting called so I want to find an alternative way.
So the question is: is there a way of invoking Objective-C from within the JS loaded in a UIWebView reliably and without didFailLoadWithError getting called on iOS 7?
Can anybody confirm Cordova is using the way above or something else?
Solutions using JavaScriptCore within a UIWebView (as opposed to external to the UIWebView) look undocumented/unsupported in iOS/fragile? For example:
Access the JavaScriptCore engine of a UIWebView
Trigger objective C method from javascript using JavaScriptCore in iOS 7 in ViewControllers