TruckMovers / cordova-plugin-remote-injection

DEPRECATED: Cordova plugin to allow a remote site to interact with cordova's javascript APIs when loaded within a cordova app.
Apache License 2.0
91 stars 95 forks source link

navigator.splashscreen not defined #43

Open jacobweber opened 6 years ago

jacobweber commented 6 years ago

I have

<preference name="AutoHideSplashScreen" value="false" />

and I'm trying to call navigator.splashscreen.hide() from my remote code. Should that work with remote injection? It seems like navigator.splashscreen is undefined when using this plugin.

markdon commented 6 years ago

An example from your code might help, but you might be trying to use the plugin before it's ready. I'm reasonable sure you need to wait for the deviceready event before you can use the splashscreen plugin. If you want to do this in your remote code you would need to create a listener for deviceready at some point before cordova.js is injected.

However maybe you might want to approach this differently. For my app, the code for hiding the splash screen is also injected using <preference name="CRIInjectFirstFiles" value="www/js/index.js" />.

and the js file itself is pretty simple:

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

    onDeviceReady: function() {
        this.receivedEvent('deviceready');
        navigator.splashscreen.hide();
    },

    receivedEvent: function(id) {
        console.log('Received Event: ' + id);
    }
};

app.initialize();
jacobweber commented 6 years ago

Hi Mark...thanks for the response. I'm having a little trouble debugging this (the Safari inspector has lately gotten in the habit of immediately closing when I inspect an iOS app).

But as far as I can tell, you're right about deviceready. However, the reason I'm not waiting for it is that my app only does so when window.cordova is defined (so that it will work in a browser as well):

if (window.cordova) {
    document.addEventListener('deviceready', startApp, false);
} else {
    startApp();
}

(and startApp has the code that accesses navigator.splashscreen)

It seems that with this plugin, window.cordova is undefined when the app first launches, and then becomes defined later. Whereas without the plugin, it gets defined immediately. Is that right? I can probably work around it if that's the case.

markdon commented 6 years ago

In a normal cordova app, you have control over when cordova.js is added, so essentially it's available immediately. For a remote page running in cordova without this plugin cordova will never be added to the page.

Guessing by this line, cordova will not be injected until after the page has loaded.

There's a method I use for detecting cordova which doesn't rely on cordova being defined. In cordova's config.xml you can append something like your package name to the user agent string. It's even possible to append different values for Andoid/iOS app in case it's useful. <preference name="AppendUserAgent" value="com.myapp.ios" />

Then in your app, to check if you're running in cordova: var isCordovaApp = window.navigator.userAgent.indexOf('com.myapp.ios') > -1;

jacobweber commented 6 years ago

Makes sense...thanks for looking into it. I ended up working around it by having my build process define an environment variable when it's going to include this plugin. I changed my startup code to wait for deviceready when either that variable or window.cordova is defined.

Might be a good idea to point out in the documentation that window.cordova won't be defined until deviceready is fired.