Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load iOS 'smart app banner' through JavaScript

I'm having some troubles with an iOS Smart App Banner, which I'm trying to add through JavaScript.

The actual smartbanner is as simple as adding this little block to the head of the HTML:

<meta name="apple-itunes-app" content="app-id=375380948">

Unfortunately, I'm quite restricted in the way I can upload my script. I can't change the HTML directly, so I'll do it through our Tag Manager, which basically does it through JavaScript. But it turns out that this doesn't work.

I've tried to simplify the case for testing:

  1. Hardcoded tag in the HTML: works (as expected)

     <meta name="apple-itunes-app" content="app-id=375380948">
    
  2. Inserted with JavaScript directly when the document is ready: works

     $(document).ready(function(){
         $("head").append('<meta name="apple-itunes-app" content="app-id=375380948">');
     });
    
  3. Inserted with JavaScript, after a setTimeout delay: DOES NOT WORK

     $(document).ready(function(){
         setTimeout(showBanner, 1);  //after 1 millisecond
     });
    
     function showBanner(){
         $("head").append('<meta name="apple-itunes-app" content="app-id=375380948">');
     }
    

Can anyone confirm or explain why this delayed JavaScript doesn't work?

Important: for testing open the page on an actual iOS device! Desktop Safari/Chrome or iOS emulator won't work. Also, don't close the banner, because it won't show up a second time.

UPDATE:

I've added some examples without jQuery, so plain 'ol JavaScript. But the results are the same. As soon as we wait for a setTimeout() the Smart App Banner fails to load.

  1. Vanilla JavaScript - direct execution. works

    showBanner();
    
    function showBanner() {
        var meta = document.createElement("meta");
        meta.name = "apple-itunes-app";
        meta.content = "app-id=375380948";
        document.head.appendChild(meta);
    }
    
  2. Vanilla JavaScript - delayed execution. DOES NOT WORK

    setTimeout(showBanner, 1);
    
    function showBanner() {
        var meta = document.createElement("meta");
        meta.name = "apple-itunes-app";
        meta.content = "app-id=375380948";
        document.head.appendChild(meta);
    }
    

UPDATE 2:

The exact same unfortunate behavior can be observed when loading the script asynchronously

  1. async loading. DOES NOT WORK

    <script src="async.js" async></script>
    

    Which then calls the same vanilla JavaScript with direct execution showBanner();

    function showBanner() {
        var meta = document.createElement("meta");
        meta.name = "apple-itunes-app";
        meta.content = "app-id=375380948";
        document.head.appendChild(meta);
    }
    

CONCLUSION:

I can only conclude that iOS Safari only looks for the smartbanner the HTML in the primary thread. And that makes me sad :-(

Only the directly available HTML, or HTML that is added synchronously through JavaScript. But no a-sync action is allowed, be it loading the JavaScript asynchronously, or using setTimeout() (or an other construct that uses eval())

like image 987
Koesper Avatar asked Jul 08 '15 10:07

Koesper


1 Answers

Since it is not possible to have safari show the native banner if it is inserted after the page load (As tested above, and confirmed by apple), the only viable workaround is not to use the native smartbanner, but to create your own.

For instance with a javascript plugin like this

like image 137
Koesper Avatar answered Oct 16 '22 11:10

Koesper