[
https://issues.apache.org/jira/browse/CB-6423?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrew Grieve resolved CB-6423.
-------------------------------
Resolution: Duplicate
Assignee: Andrew Grieve
Believe the issue here is that same that I just fixed in CB-5488. There is a
race condition for creating the iframe, where document.body doesn't exist yet
at times.
For now, a work around would be to put the `<script src="cordova.js">` tag
after <body>
> (iOS) cordova.js: iOSExec() not working after upgrading from Cordova 3.0 to
> 3.4
> -------------------------------------------------------------------------------
>
> Key: CB-6423
> URL: https://issues.apache.org/jira/browse/CB-6423
> Project: Apache Cordova
> Issue Type: Bug
> Components: CordovaJS, iOS
> Affects Versions: 3.4.0
> Reporter: Joel Rubio
> Assignee: Andrew Grieve
> Labels: cordovajs, ios, upgrade
>
> Hi there,
> I recently upgraded my working PhoneGap app from 3.0 to 3.4. In iOS, the app
> wouldn't go past the splashscreen. It would get stuck while trying to fetch a
> local file (in file:/// dir) through an XHR.
> I managed to trace the problem to the iOSExec function in cordova.js. Before
> the upgrade, it would determine bridgeMode the following way:
> bridgeMode = navigator.userAgent.indexOf(' 4_') == -1 ?
> jsToNativeModes.XHR_NO_PAYLOAD : jsToNativeModes.IFRAME_NAV;
> In cordova.js 3.4 it is determined the following way:
> bridgeMode = navigator.userAgent.indexOf(' 5_') == -1 ?
> jsToNativeModes.IFRAME_NAV: jsToNativeModes.XHR_NO_PAYLOAD;
> Notice the switch in the expressions.
> This led to any iOS device with a version other than 5 not working. Using the
> jsToNativeModes.IFRAME_NAV bridgeMode would lead to the default case in the
> subsequent switch statement in which it determines what to do according to
> the bridgeMode.
> switch (bridgeMode) {
> case jsToNativeModes.XHR_NO_PAYLOAD:
> case jsToNativeModes.XHR_WITH_PAYLOAD:
> case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
> // This prevents sending an XHR when there is already one being
> sent.
> // This should happen only in rare circumstances (refer to unit
> tests).
> if (execXhr && execXhr.readyState != 4) {
> execXhr = null;
> }
> // Re-using the XHR improves exec() performance by about 10%.
> execXhr = execXhr || new XMLHttpRequest();
> // Changing this to a GET will make the XHR reach the URIProtocol
> on 4.2.
> // For some reason it still doesn't work though...
> // Add a timestamp to the query param to prevent caching.
> execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);
> if (!vcHeaderValue) {
> vcHeaderValue = /.*\((.*)\)/.exec(navigator.userAgent)[1];
> }
> execXhr.setRequestHeader('vc', vcHeaderValue);
> execXhr.setRequestHeader('rc', ++requestCount);
> if (shouldBundleCommandJson()) {
> execXhr.setRequestHeader('cmds',
> iOSExec.nativeFetchMessages());
> }
> execXhr.send(null);
> break;
> case jsToNativeModes.IFRAME_HASH_NO_PAYLOAD:
> case jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD:
> execHashIframe = execHashIframe || createHashIframe();
> // Check if they've removed it from the DOM, and put it back if
> so.
> if (!execHashIframe.contentWindow) {
> execHashIframe = createHashIframe();
> }
> // The delegate method is called only when the hash changes, so
> toggle it back and forth.
> hashToggle = hashToggle ^ 3;
> var hashValue = '%0' + hashToggle;
> if (bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
> hashValue += iOSExec.nativeFetchMessages();
> }
> execHashIframe.contentWindow.location.hash = hashValue;
> break;
> default:
> execIframe = execIframe || createExecIframe();
> // Check if they've removed it from the DOM, and put it back if
> so.
> if (!execIframe.contentWindow) {
> execIframe = createExecIframe();
> }
> execIframe.src = "gap://ready";
> }
> The default case did nothing.
> Making it always use jsToNativeModes.XHR_NO_PAYLOAD allows my app to work
> again with any iOS version but I feel like I'm losing certain advantages from
> the upgrade. Which are they? Why were the Ternary Operator expressions
> switched around? Which could be a possible reason why my app, which worked
> just fine before the upgrade, would stop working because of this change? Is
> there a better solution than the one I implemented?
> Thanks,
> -JR.
--
This message was sent by Atlassian JIRA
(v6.2#6252)