EddyVerbruggen / Custom-URL-scheme

:link: Launch your Cordova/PhoneGap app by a Custom URL scheme like mycoolapp://
1.03k stars 365 forks source link

A better way to call openHandleURL !!! #337

Open rolinger opened 2 years ago

rolinger commented 2 years ago

the openHandleURL fires way before the app fully initializes EVEN when set in the deviceReady section of app.js or main.js. This is particularly worse when an app launches for the very first time. Example scenario: User installs the app BUT doesn't open it - the app has never initialized on the users phone before. Then the user clicks on an external URL Scheme (or QR Code) that redirects them into the app. This will cause window.handleOpenURL to fire well before the first time app initialization is complete and the redirected URL won't work.

For years, everyone has been using the following:

    window.handleOpenURL = function(url) {
        setTimeout(_ => {
          .... do stuff here
       },0) ;

But even beyond the first time app initialization scenario above, working off of timers can bite you in the ass because sometimes some things take just hair longer than your timeout timer - and then your redirected URL will fail within your app.

To manage this I changed to the following method:

    window.handleOpenURL = function(url) {
      var doURL = $interval(function() { 
        if (getDB("app_initialized") !== null) {    // <----- specific app local storage value is set
          $interval.cancel(doURL) ;
          openURL(url) ;
        }
      },100) ;
      function openURL(url) {
        setTimeout(_ => {
           ... do stuff here
       },0) ;
    }

Change your interval trigger to whatever you want....but this ensures you can control WHEN handleOpenURL will fire. In my case, I set a bunch of localStorage variables upon first time install....app_initialized is the last one to be set. When its set, then my environment is ready to go.

rolinger commented 2 years ago

Well...the above works but I also found after extensive testing that about 25% of the time the app got stuck in the $interval and the function of the app that set the variable needed variable to break the $internal was never getting triggered. Not certain why though, being asynchronous the other function should have triggered. So I adapted it to this:

$rootScope.openURL = null ;
window.openHandleURL(url) {
   if (getDB("app_initialized") == 1) {
      // app fully loaded or already running in back ground
      processURL(url) ;
   } else {
      // if app not fully initialized, capture the URL
      // then do something with it later.
      $rootScope.openURL = url ;
   }
} ;

And then later on in the section that checks if app is initialized with all the appropriate variables set/saved/etc, then I simply check for:

if ($rootScope.openURL !== null) {
   $rootScope.openURL = null ;
      processURL(url) ;
}

This actually is the cleanest solution. No $internval, no setTimeout - just do something with the URL when everything else is set, initialized and ready to go.