Check if URL scheme is supported in javascript

只愿长相守 提交于 2019-11-26 06:11:38

No, not from a webpage.

Not seamlessly. But there is a way similar to checking if a pop-up was blocked or not.

When you try a URL scheme which is not supported, Safari will warn the user that it doesn't know what to do with it and stay on the same page.

So if you gave your app-call some time to activate, say 300 ms, and then do something else to respond to the non-existence of the scheme.

It's not the prettiest but it works:

function startIThrown(){
  document.location = 'ithrown://restart';
  setTimeout(function(){
    if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
      document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
    }
  }, 300);
}

<a href="#" onclick="startIThrown()">Restart iThrown</a>
mrahman

Here is a solution that does not show the popup when you come back from the app, it assumes you've been gone longer than 400 ms:

function startiThrown() {
    document.location = appurl;
    var time = (new Date()).getTime();
    setTimeout(function(){
        var now = (new Date()).getTime();

        if((now - time)<400) {
            if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
            document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
            }
         }
    }, 300);
}
Thomas - BeeDesk

I found pagehide event to be more robust than depending on system time. For those of us who prefers a non-jQuery favor, here is the snippet.

  var appurl = 'custom://url';
  var appstore = 'https://itunes.apple.com/us/app/your-app';

  var timeout;
  function preventPopup() {
    clearTimeout(timeout);
    timeout = null;
    window.removeEventListener('pagehide', preventPopup);
  }
  function startApp() {
    window.location = appurl;
    timeout = setTimeout(function(){
      if(confirm('You do not seem to have the App installed, do you want to go download it now?')){
        document.location = appstore;
      }
    }, 1000);
    window.addEventListener('pagehide', preventPopup);
  }
Loris Guignard

Another great (at least working in latest browser versions) workaround is to check if the browser window has focus after a short timeout, this way you can show a dialog box to the user only if the URI scheme didn't work

HTML:

<a class="uri-link" data-uri="qobuzapp://" href="#">URI</a>​

Javascript (using jQuery here):

var windowHasFocus;

$(window).focus(function() {
  windowHasFocus = true;
}).blur(function() {
  windowHasFocus = false;
});

function goToUri(uri) {
  window.location = uri;
  setTimeout(function(){
    if (windowHasFocus) {
      if (confirm('You do not seem to have Qobuz installed, do you want to go download it now?')){
        window.location = 'http://www.qobuz.com';
      }
    }
  }, 100);
}

$('a').on('click', function(){ 
  goToUri($(this).data('uri')); 
});​

Here is a working jsFiddle, just update it with your own URI scheme: http://jsfiddle.net/mF6TZ/

Starting from iOS 6.0 Apple presented the Smart App Banners which do what most of us are looking for:

  • Send to App Store if the app isn't installed.
  • Open the App with a specific deep link, using the app-argument param.

Include the following meta tag:

<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">

taken from here: Safari Web Content Guide

Here is a variation on the previous 2 solutions. It will create a link that can be opened in Google Chrome. If it fails it opens the link using http

<script>
 function checkChrome(h){
  document.location=h;
  var time = (new Date()).getTime();
  setTimeout(function(){
   var now = (new Date()).getTime();
   if((now-time)<400) {
    if(confirm('Missing Chrome. Download it now?')){
     document.location = 'http://itunes.apple.com/us/app/chrome/id535886823?mt=8';
    } else {
     document.location=h.replace('googlechrome','http');
    }
   }
  }, 300);
 }
</script>

<a href="googlechrome://www.google.com" onclick="checkChrome(this.href);return false;">Open Google with Chrome</a>
k3erg

This is based on the answer of mrahman. As noted, by JoshNaro new Date() gives back a wrong date when called inside the timeout. Tests suggest that the date is not updated in threads that are started before the app is deactivated.

A further ugly setTimeout called after activation will create a new thread with the current date.

This was tested on iOS 8.

function startiThrown() {
    document.location = appurl;
    var time = (new Date()).getTime();
    setTimeout(function(){
        setTimeout(function(){ // <-- start new thread after activation
            var now = (new Date()).getTime();
            if((now - time)<400) {
                if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
                    document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
                }
            }
        }, 10); // <-- start new thread after activation
    }, 300);
}

I try to use just the 'pagehide' event, but then it not work into Firefox. I created this version here http://jsfiddle.net/thiagomata/6tvoc4f1/2/ what works in Firefox, Google Chrome and Safari. I have not tested in Internet Explorer yet.

One thing what was necessary to make it work into Firefox, was use Iframe to set the src. This allows me to call the app without leaving my page.

<a class="uri-link" href="#" 
  data-uri-app="myapp://" 
  data-url-app-not-found="http://www.google.com?q=not-found-link"
  >
  Example 1
</a>​
<a class="uri-link" href="#" 
  data-uri-app="myapp://" 
  data-url-app-not-found="http://www.google.com?q=not-found-link"
  data-url-app-found="http://www.google.com?q=found-link"
  >
  Example 2
</a>​
<a class="uri-link"  href="#"
  data-uri-app="notexists://" 
  data-url-app-not-found="http://www.google.com?q=not-exists"
>
  Example 3
</a>​
<iframe id="callapp" style="display:none"></iframe>
Lito

I have this comment https://stackoverflow.com/a/18715513/49114 with a jQuery plugin to add alternative app link to regular links.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!