39

My question is about iOS9 only!

I have an HTML landing page, and I try to redirect the user to my app via URL scheme if the app is installed, or redirect to the Appstore otherwise.

My code is:

document.addEventListener("DOMContentLoaded", function(event) {

  var body = document.getElementsByTagName('body')[0];
  body.onclick = function () {
    openApp();
  };
});

var timeout;

function preventPopup() {

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

function openApp(appInstanceId, platform) {

  window.addEventListener('pagehide', preventPopup);
  document.addEventListener('pagehide', preventPopup);

  // create iframe
  var iframe = document.createElement("iframe");
  document.body.appendChild(iframe);
  iframe.setAttribute("style", "display:none;");
  iframe.src = 'myscheme://launch?var=val';

  var timeoutTime = 1000;
  timeout = setTimeout(function () {

    document.location = 'https://itunes.apple.com/app/my-app';

  }, timeoutTime);
}

The problem is that the iframe trick doesn't work in Safari iOS9.

Any idea why?

My iframe trick based on this answer.

Community
  • 1
  • 1
gran33
  • 12,421
  • 9
  • 48
  • 76
  • the **openApp** redirect to safari or not – Anbu.Karthik Sep 21 '15 at 07:43
  • @Anbu.Karthik What do u mean? – gran33 Sep 21 '15 at 07:44
  • sorry , in your condition redirect to safari or not – Anbu.Karthik Sep 21 '15 at 07:45
  • But I want to switch app if possible (and don't show any alert if it's impossible) or redirect to app store. I don't want to redirect any way.. – gran33 Sep 21 '15 at 07:48
  • friend , I don't know javascript, but I worked on URL schema on more than three apps in iOS, I surely support you to find the solution , – Anbu.Karthik Sep 21 '15 at 07:54
  • Friend, Thanks for your help, and same thanks to your support. I asked about `JavaScript`+`Safari`+`iOS`+`URLScheme` not only about `iOS` and not only about `URLScheme` – gran33 Sep 21 '15 at 07:58
  • @gran33 have you tested it removing `display:none`? Maybe Safari on iOS9 doesn't open url/iframe not displayed... – Luigi Saggese Sep 24 '15 at 07:20
  • @LuigiSaggese Yes, same problem :/ – gran33 Sep 25 '15 at 08:38
  • @gran33 i have same issue! Some websites made it with 2-3 redirect (i.e. LinkedIn). I don't like st.derrick solution, but maybe replacing redirect to store with a redirect to another, or same page skipping uri-scheme launch, could be a solution. What do you think? – Luigi Saggese Sep 25 '15 at 08:55
  • @LuigiSaggese I think we can't run away from the big brother (He'll keep watching us..), and we must use `Universal Links` by Apple – gran33 Sep 28 '15 at 18:50

5 Answers5

23

The iframe trick no longer works -- my guess is that Apple knows it will encourage more developers to implement Universal Links, more quickly.

You can still set window.location='your-uri-scheme://'; and fallback to the App Store after 500ms. There is a "dance" between popups if you take this approach, as we do at Branch (we do as a fallback if Universal Links don't work).

window.location = 'your-uri-scheme://'; // will result in error message if app not installed
setTimeout(function() {
   // Link to the App Store should go here -- only fires if deep link fails                
   window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8";
}, 500);

I wish I had a better answer for you. iOS 9 is definitely more limited.

For a helpful overview of what's needed for Universal Links should you go that route, check out my answer here or read this tutorial

Community
  • 1
  • 1
st.derrick
  • 4,769
  • 2
  • 24
  • 25
  • @formatjam yes, if the app is not installed. It's unfortunate. – st.derrick Oct 03 '15 at 17:51
  • When the location change and the fallback timer are invoked from a user interaction event (e.g. an onclick handler on a button), as opposed to running e.g. onload, the location change in the timer always executes and the user always ends up being bumped to the app store. It looks like in this interactive scenario, the "Open this page in 'appname'" popup dialog that gets shown as a result of the first window.location assignment doesn't prevent further location changes from happening. Also, it appears the timeout can be as low as 1ms, I didn't see any diff between 500 and 1, Chrome included. – obiuquido144 Oct 05 '15 at 05:06
  • Further to my comment above, to ensure the flow works as expected even in the interactive scenario, you will need to 'create indirection' by wrapping the entire thing (i.e. incl. the first window.location assignment) in another timeout. E.g.: setTimeout(function () {window.location = 'your-uri-scheme://'; setTimeout(function () { window.location = 'https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8' }, 1); }, 1); – obiuquido144 Oct 05 '15 at 06:56
  • 2
    @obiuquido144 I don't see how wrapping it in another timeout help. Im my case it didn't. – Michael Oct 20 '15 at 08:08
  • 5
    This doesn't seem to be working for me - it will show the "Open in app myapp?" dialog for a second and then it will redirect to my fallback url in the setTimeout method. Any idea as to why? – tommybond Dec 14 '15 at 18:21
  • Has anyone figured this out? – tommybond Dec 21 '15 at 18:28
  • @tommy.bonderenka Looks like a 9.2 thing where the "Open this page" dialog is no longer modal, so the redirect is not prevented. – jamix Feb 04 '16 at 17:22
  • 1
    on iOS versions >12.3, after opening the App from Safari it redirects to App Store in a split second. – enigma Jul 31 '19 at 06:13
3

As already mentioned setting window.location on iOS 9 still works. However, this brings up an Open in App dialog. I've put an example on https://bartt.me/openapp that:

  1. Launches Twitter when the Open in Twitter app is clicked.
  2. Falls back to the Twitter app in the App Store.
  3. Redirects to Twitter or the App Store without the user selecting Open in the Open in App dialog.
  4. Works in all browsers on iOS and Android.

Look at the source of https://lab.bartt.me/openapp for more information.

  • It does again, was temporarily turned off. – Bart Teeuwisse Oct 08 '15 at 02:51
  • Re point 3, I tested in iOS 9.3.5, and it doesn't appear to be able to open Twitter without the user clicking open in the "Open" button in the "Open this page in 'Twitter'" dialog. – tul Sep 14 '16 at 21:57
  • +1 Does it work in iOS 9 without the "Open in app" dialog? Thanks for sharing. May you please add your code to the post to be in compliance with Stack Overflow rules. – Noitidart Jun 20 '17 at 10:00
  • @BartTeeuwisse can you please provide the code? The linked page results in a 404. Thanks! – glutengo Sep 08 '17 at 09:30
  • @der_gluateng I've updated the link to the source code. – Bart Teeuwisse Sep 11 '17 at 18:54
  • This doesn't seem to work in the iOS Safari browser (anymore?). When user doesn't have Twitter installed on iOS 13 and taps the button, you get the generic 'Safari cannot open this page because it's invalid' alert. – Thermometer Jan 13 '21 at 15:33
1

Maybe try giving you app support to Universal Links

Idea: Avoid custom (JavaScript, iframe) solutions in Safari, replace you code with a supported Universal Link.

Example

<html>
<head>
...
</head>
<body>
    <div class"app-banner-style">
        <a href="http://yourdomain.com">In app open</a> 
    </div>
...content
</body>
</html>

if you app support Universal Links (e.g. yourdomain.com), you muss configure your domain (and path) and iOS9 should be react to it link opening you App. That is only theory, but I guess should be work :)

https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12

0

iframe hack doesn't work in ios9 anymore. Possible solution is use two buttons. Example:

$('#goToStoreBtn').text( "go to store" ).click(function(event){
    event.preventDefault();
    event.stopPropagation();
    window.location = storeUrl; // https://itunes.apple.com/...
});

$('#goToAppBtn').text( "go to app" ).click(function(event){
    event.preventDefault();
    event.stopPropagation();
    window.location = appUrl;  // myApp://...
});
xac
  • 310
  • 3
  • 9
-1

This is relatively old thread, but I have created a library that supports deeplinking on most of the modern mobile browsers. But this requires separate deeplinking page which needs to be hosted in different domain to support universal linking in ios9 facebook browser.

https://github.com/prabeengiri/DeepLinkingToNativeApp

prabeen giri
  • 803
  • 7
  • 18