[ 
https://issues.apache.org/jira/browse/CB-6423?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13982793#comment-13982793
 ] 

Christophe Decaux commented on CB-6423:
---------------------------------------

I get this issue too.
Symptom for me is that I get this during app startup: 
[Error] TypeError: 'null' is not an object (evaluating 
'document.body.appendChild')
        createExecIframe (cordova.js, line 833)
        iOSExec (cordova.js, line 1009)
        getInfo (network.js, line 46)
        (fonction anonyme) (network.js, line 57)
        fire (cordova.js, line 750)
        (fonction anonyme) (cordova.js, line 1195)
        f (cordova.js, line 622)
        fire (cordova.js, line 750)
        (fonction anonyme) (cordova.js, line 1183)
        onScriptLoadingComplete (cordova.js, line 1369)
        scriptLoadedCallback (cordova.js, line 1386)

And 5 seconds later a message telling me that deviceready didn't complete

I'm seeing too this behavior on all iOS simulator platform/OS combinations 
And like Joel, if I force bridgeMode to jsToNativeModes.XHR_NO_PAYLOAD, 
everything is fine



> (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
>              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)

Reply via email to