Chase
Chase

Reputation: 2326

Cordova filePluginIsReady event never fires in iOS using cordova-plugin-file

I've been debugging working with persistent data for weeks... and I think I've finally found *part of the problem.

Most of my tests are running the browser platform in Chrome 59 on Windows 10, but I'm also building my app with Phonegap Build, and installing it on my iPhone (iOS 10.3.2).

According to the Cordova doc's Chrome querks:

Chrome filesystem is not immediately ready after device ready event. As a workaround you can subscribe to filePluginIsReady event. Example:

window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);

You can use window.isFilePluginReadyRaised function to check whether event was already raised.

I wasn't able to get the 'filePluginIsReady' event listener working, so finally tried console.logging window.isFilePluginReadyRaised, and sure enough it's false!

As a matter of desperation, I tried adding a timer

setTimeout(function(){                        
     console.log('filePluginIsReady: ' + window.isFilePluginReadyRaised());

     consol.append(document.createElement("br"));
     consol.append('filePluginIsReady: ', window.isFilePluginReadyRaised());
 }, 5000);

And I get true! I tried lowering it down to 1000ms and it still works, but without the timeout, I get false. I'm appending the console log to a dom element so I can debug this on my phone, which brings me to the problem: I get nothing...

I get the beautiful green "device is ready", but after five seconds, my "console" remains blank. No result from window.isFilePluginReadyRaised()

My HTML

<div class="app">
    <h1>Apache Cordova</h1>
    <div id="deviceready" class="blink">
        <p class="event listening">Connecting to Device</p>
        <p class="event received">Device is Ready</p>
    </div>

    <h3>Console:</h3>
    <pre id='consol'></pre>
</div>

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="dist/build.js"></script>

JS

var app = {
    initialize: function () {
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    },

    onDeviceReady: function () {
        this.receivedEvent('deviceready');

        setTimeout(function(){                        
            console.log(cordova.file);

            console.log('filePluginIsReady: ' + window.isFilePluginReadyRaised());

            consol.append(document.createElement("br"));
            consol.append('filePluginIsReady: ', window.isFilePluginReadyRaised());
        }, 5000);
    },

    receivedEvent: function (id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    },
};

app.initialize();

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="[email protected]" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <preference name="iosPersistentFileLocation" value="Library" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
    <engine name="browser" spec="^4.1.0" />
    <plugin name="cordova-plugin-file" spec="^4.3.3" />
    <plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
</widget>

Edit: I discovered my file structure may have been incorrect. Phonegap specifies that the config should be in the www directory, while mine was a level up. Fixing this did not fix the issue. I also checked the Phonegap Build logs:

--------------------------------------------------------------------------------
PLUGIN OUTPUT
--------------------------------------------------------------------------------
Fetching plugin "cordova-plugin-file@^4.3.3" via npm
Installing "cordova-plugin-file" at "4.3.3" for ios
Fetching plugin "cordova-plugin-compat" via npm
Installing "cordova-plugin-compat" at "1.1.0" for ios
Fetching plugin "cordova-plugin-whitelist@^1.3.2" via npm
Installing "cordova-plugin-whitelist" at "1.3.2" for ios

Upvotes: 0

Views: 594

Answers (1)

dotNetkow
dotNetkow

Reputation: 5313

Updated answer, after reading the question a bit closer :)

The File Plugin link mentions: "Chrome filesystem is not immediately ready after device ready event." In your provided code sample, you're hooking into the "deviceready" event, but as the docs mention, that won't work for Google Chrome, but should for iOS (Safari browser). To tweak my original answer a bit:

Try registering both the "filePluginIsReady" and "deviceready" event as soon as possible, attaching it to the "onload" method of the HTML body tag:

    <body onload="initialize();">
         <div class="app">
             <!-- all other html -->
         </div>
         <script type="text/javascript">
              function onFilePluginReady() {
                     // use file plugin
                     console.log("onFPReady: " + cordova.file);
              }
              function onDeviceReady() {
                     // use file plugin - iOS or other mobile platforms
                     console.log("onDeviceReady: " + cordova.file);
              }
              function initialize() {
                  // special event for Google Chrome (Android)
                  document.addEventListener('filePluginIsReady', onFilePluginReady, false);
                  // event for iOS and others
                  document.addEventListener("deviceready", onDeviceReady, false);

              }
         </script>
    </body>

Upvotes: 1

Related Questions