43

I've been looking for a way to open a native iOS app from the browser. I found a decent solution here: Is it possible to register a http+domain-based URL Scheme for iPhone apps, like YouTube and Maps?

This solution works great when you have the app installed. but when a user doesn't have this app installed - safari fires an error message which says "Safari cannot open the page because the address is invalid."

Is there a way to prevent this behaviour and instead to prompt the user to download the app?

Community
  • 1
  • 1
Dima Feldman
  • 708
  • 1
  • 10
  • 17

7 Answers7

27

Here is a solution that works for me:

var timeout;

function preventPopup() {
    clearTimeout(timeout);
    timeout = null;
    window.removeEventListener('pagehide', preventPopup);
}

function openApp() {    
    $('<iframe />')
    .attr('src', appurl)
    .attr('style', 'display:none;')
    .appendTo('body');

    timeout = setTimeout(function() {
            document.location = appstore;
    }, 500);
    window.addEventListener('pagehide', preventPopup);
} 
ElizaS
  • 850
  • 1
  • 9
  • 22
  • 1
    hey you can replace document.location = appstore; with: window.open( appstore, "_system" ); and it will work for both – ElizaS Sep 15 '14 at 15:35
  • great answer also maybe U know: otherwise when app is installed and i returned back to safari on ipad (for example) - i see for 1-2 sec alert: "open this app in app store?" - is it real to hide it? – brabertaser19 Apr 02 '15 at 12:04
  • 6
    The iframe trick does not work in iOS9. See here for discussion specific to iOS9+: https://stackoverflow.com/questions/32689483/ios9-try-to-open-app-via-scheme-if-possible-or-redirect-to-app-store-otherwise – user456584 Oct 02 '15 at 20:27
  • I'd recommend abstracting this to https://branch.io. This JS is hosted and updated with every new version of iOS9 so you don't have to worry about it. Unfortunately, as the commenters indicate, iOS9 broke all of this but we (the Branch team) are working with Apple to get it fixed. We don't believe it was intentional. – Alex Austin Nov 16 '15 at 05:23
  • @ElizaS, is the `appstore` above supposed to be a variable or a URL to the apple appstore? – ayjay Jan 06 '16 at 21:40
6

use iframe.

$('<iframe />').attr('src', "appname://").attr('style', 'display:none;').appendTo('body');
laaposto
  • 11,835
  • 15
  • 54
  • 71
Kohei Iwasaki
  • 69
  • 1
  • 4
  • maybe U know: otherwise when app is installed and i returned back to safari on ipad (for example) - i see for 1-2 sec alert: "open this app in app store?" - is it real to hide it? – brabertaser19 Apr 02 '15 at 12:05
2

For solving this and avoid no wanted iOS safari alert I've used a different approach handle also an iframe but without jquery and listener events. It works perfectly.

    var iframe = document.createElement("iframe");

    iframe.style.border = "none";
    iframe.style.width = "1px";
    iframe.style.height = "1px";
    iframe.onload = function () {
        document.location = alt;
    };
    iframe.src = nativeSchemaUrl; //iOS app schema url

    window.onload = function(){
        document.body.appendChild(iframe);
    }

    setTimeout(function(){
        window.location = fallbackUrl; //fallback url
    },300);
akruspe
  • 141
  • 1
  • 14
1

I'm using meta refresh as fallback because this works without javascript. This code works in iOS and Android.

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="refresh" content="1; url=http://www.facebook.com">
    <title>Redirecting..</title>
    <script>
    function tryOpenApp() {
                var iframe = document.createElement("iframe");
                iframe.style.border = "none";
                iframe.style.width = "1px";
                iframe.style.height = "1px";
                iframe.src = "fb://feed/";
                document.body.appendChild(iframe);
    }
    </script>
  </head>
  <body onload="tryOpenApp()">
  </body>
</html>

Test http://static-pmoretti.herokuapp.com/deep-link/

Pablo Moretti
  • 1,374
  • 13
  • 10
  • Hi Pablo, after trying to know how it worked, I saw that the important code in here is the meta tag. Without it, doesn't work. So why is the iframe created then? Thanks! – Dani G. May 10 '19 at 12:25
0

i use it in react like this

<iframe style={{width:0,height:0}} srcDoc={`<script> document.location=\`yourschema://autourl=${escape(document.location.toString())}\`;</script>`}></iframe>
rabie jegham
  • 125
  • 2
  • 3
-1

The right way to do this is to use Smart App Banners: https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html

If your app is not installed, the banner will let the user install it. If it is installed, it will open the app, and you have a way of specifying custom URL arguments to pass to the app.

Thomas Deniau
  • 2,488
  • 1
  • 15
  • 15
  • 4
    Adding a Smart App Banner has its drawbacks. For example if the user closes it (presses the X button), there is no way to show it again. – caisah Apr 05 '16 at 14:50
-1

For me this does the job:

window.open(appLink, '_system')`

window.open(appstoreLink, '_system')

Works for android and ios. If the first one can't be opened the second one is called without alert or something. Otherwise it just opens the app.

MEDZ
  • 2,227
  • 2
  • 14
  • 18