Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mobile Safari Page unload/hide/blur for Deep Linking

I am looking for an event on mobile safari that will detect when the page has been hidden due to a redirect. I want to open my app directly if a user has it installed, then attempt facebook if it is installed, and if not then go to the webpage for that id.

  1. If 'myapp' is installed, then myapp is opened. But the safari tab still gets redirected to facebook.com
  2. If 'myapp' is not installed, but facebook is, then facebook ios app is opened. But the safari tab still gets redirected to facebook.com

I've created a test link with the following HTML/JS:

    <!DOCTYPE html>     <html>     <head>             <title>Redirect Test</title>             <script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'></script>             <meta name='viewport' content='initial-scale = 1.0,maximum-scale = 1.0' />     </head>     <body>     <button>Open Oreo</button>     <script type='text/javascript'>     jQuery(function(){             jQuery( 'button' ).on( 'click', function(){                     var myid = null, fbid = null;                      // Watch for page leave to kill timers                     jQuery( window ).on( 'pagehide pageshow blur unload', function(){                             if ( myid ) {                                     clearTimeout( myid );                             }                             if ( fbid ) {                                     clearTimeout( fbid );                             }                     });                      window.location = "myapp://fbprofile/oreo";                     var myid = setTimeout(function(){                              // My app doesn't exist on device, open facebook                             window.location = "fb://profile/oreo";                             fbid = setTimeout(function(){                                      // Facebook doesn't exist on device, open facebook mobile                                     window.location = "https://www.facebook.com/oreo";                             }, 100);                     }, 100);             });     });     </script>     </body>     </html> 
like image 270
Corey Hart Avatar asked Feb 05 '13 19:02

Corey Hart


1 Answers

Nice code.
EDIT: (removed suggestion about adding return false;)

Try setting a check within your setTimeout functions in stead of just clearing the Timeouts. (I find that clearing is much more effective for intervals in stead of simple 1-time setTimeout calls). Also, I would check to make sure the user isn't on a desktop browser before trying a native app protocol like my app:// or fb:// as those browsers will try to follow that location and end up displaying an error.

Try:

<!DOCTYPE html> <html> <head>     <title>Redirect Test</title>     <script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'></script>     <meta name='viewport' content='initial-scale = 1.0,maximum-scale = 1.0' /> </head> <body> <button>Open Oreo</button> <script type='text/javascript'> var mobileExp = /android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile|o2|opera mini|palm( os)?|plucker|pocket|pre\/|psp|smartphone|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce; (iemobile|ppc)|xiino/i;  jQuery(function(){     jQuery( 'button' ).on( 'click', function(){          // Don't give desktop browsers a chance to fail on a nativeapp:// protocol         if(!mobileExp.test(navigator.userAgent)) {             window.location = "https://www.facebook.com/oreo";             return;         }          var clicked = +new Date, timeout = 100;          window.location = "myapp://fbprofile/oreo";          setTimeout(function(){             // If we're still here after a (timeout), try native facebook app             if (+new Date - clicked < timeout*2){                 console.log('clicked '+ (+new Date - clicked) +' ago- go to FB');                 window.location = "fb://profile/oreo";             } else {                 console.log('too late for facebook');             }             setTimeout(function(){                 // If we're still here after another (timeout), try facebook web app                 if (+new Date - clicked < timeout*2){                     console.log('clicked '+ (+new Date - clicked) +' ago- go to browser');                     window.location = "https://www.facebook.com/oreo";                 } else {                     console.log('too late for browser');                 }             }, timeout);         }, timeout);     }); }); </script> </body> </html> 

Of course, un-comment the console logs and do some experimenting with the value of timeout. This exact code tested successfully in IOS 6.1 Safari and Safari 6.0.2 Mac. Hope it helps!

like image 197
goddogsrunning Avatar answered Sep 17 '22 11:09

goddogsrunning