Como verificar se um aplicativo está instalado a partir de uma página da web em um iPhone?

142

Quero criar uma página da web, uma página que redirecionará um iPhone para a loja de aplicativos, se o iPhone não tiver o aplicativo instalado, mas se o iPhone tiver o aplicativo instalado, quero que ele abra o aplicativo.

Eu já implementei um URL personalizado no aplicativo para iPhone, então eu tenho um URL para o aplicativo que é algo como:

myapp://

E se esse URL for inválido, desejo que a página seja redirecionada para a loja de aplicativos. Isso é possível em tudo?

Se eu não tenho o aplicativo instalado no telefone e escrevo o myapp: // url no safari, tudo o que recebo é uma mensagem de erro.

Mesmo se houver um truque feio com javascript, eu realmente gostaria de saber?

Joakim Engstrom
fonte
1
Isso continua mudando em todas as versões do iOS - o iOS9 simplesmente quebrou tudo de novo. Eu recomendo usar um serviço como o branch.io para cuidar disso para você. Ajudei a criar partes do serviço de link Branch, e atualmente ele lida com mais de 6000 casos diferentes de borda de redirecionamento ... loucos.
Alex Austin
1
Em 2017, se sua necessidade é a de link para o aplicativo de e-mails, você deveria dar uma olhada em minha resposta: stackoverflow.com/questions/13044805/...
Sebastien Lorber

Respostas:

199

Tanto quanto eu sei, você não pode, em um navegador, verificar se um aplicativo está instalado ou não.

Mas você pode tentar redirecionar o telefone para o aplicativo e, se nada acontecer, redirecione o telefone para uma página especificada, assim:

setTimeout(function () { window.location = "https://itunes.apple.com/appdir"; }, 25);
window.location = "appname://";

Se a segunda linha do código der um resultado, a primeira linha nunca será executada.

Espero que isto ajude!

Pergunta semelhante:

missemisa
fonte
20
Atualmente no iOS 6.1.2, isso parece funcionar apenas no modo de aplicativo da web. Se você usar o aplicativo diretamente do navegador, ele abrirá o aplicativo externo conforme o esperado, mas o tempo limite também será acionado e o navegador será redirecionado.
Mika Tuupola
Eu precisava de uma solução como esta para iOS e Android. Eu encontrei esta resposta integrada em uma solução multi-plataforma aqui: gist.github.com/FokkeZB/6635236#file-all-in-one-php
Justin
4
Se o aplicativo não estiver instalado, ele lança um alerta feio de 'página não encontrada'. De qualquer forma, podemos suprimir essa
Akshat Agarwal
3
@AkshatAgarwal, você pode por favor elaborar sobre 'alerta página não encontrada' como código para suprimir
Harpreet
2
Existem novas maneiras de implementar isso agora no Android e no iOS. Dê uma olhada nos links de aplicativos para Android e nos links universais para iOS
maledr53
157

Para promover a resposta aceita, às vezes você precisa adicionar código extra para lidar com as pessoas que retornam o navegador após o lançamento do aplicativo - essa função setTimeout será executada sempre que o fizerem. Então, eu faço algo assim:

var now = new Date().valueOf();
setTimeout(function () {
    if (new Date().valueOf() - now > 100) return;
    window.location = "https://itunes.apple.com/appdir";
}, 25);
window.location = "appname://";

Dessa forma, se houver um congelamento na execução do código (ou seja, troca de aplicativo), ele não será executado.

Alastair
fonte
2
Esta solução é muito melhor do que outros, eu tive que aumentar o tempo em 50
Magico
1
Meu comentário sobre a falha no iOS 7 foi falso: eu simplesmente tive que aumentar os 100 ms para alguns segundos (não é necessário que seja tão curto assim mesmo).
devios1
Em vez de itunes.apple.com/appdir , salve uma etapa (sem esperar um redirecionamento http) e vincule diretamente ao esquema de URL da loja de aplicativos. Por exemplo: itms: //itunes.apple.com/br/app/yelp/id284910350
Justin
Impressionante, está funcionando bem para aplicativos iOS, o mesmo código é redirecionado para os dois URLs ao mesmo tempo nos aplicativos Android. você faz para o Android para abrir aplicativos e loja de jogos?
Mehul Dudhat
5
Isso sempre abre meu aplicativo e a loja de aplicativos, mesmo aos 50 anos. IOS 12
Josh Wolff
27

O iOS Safari possui um recurso que permite adicionar um banner "inteligente" à sua página da web que vinculará ao seu aplicativo, se estiver instalado, ou à App Store.

Você faz isso adicionando uma metatag à página. Você pode até especificar um URL detalhado do aplicativo se desejar que o aplicativo faça algo especial ao carregar.

Os detalhes estão na página de Promoção de aplicativos da Apple com banners de aplicativos inteligentes .

O mecanismo tem as vantagens de ser fácil e apresentar um banner padronizado. A desvantagem é que você não tem muito controle sobre a aparência ou o local. Além disso, todas as apostas serão desativadas se a página for visualizada em um navegador que não seja o Safari.

brainjam
fonte
2
Mas ele não mostra bandeira aplicativo se o usuário não instalá-lo
TomSawyer
Nem os links universais nem os banners inteligentes funcionam para mim. Preciso ter vários links de aplicativos nativos para aplicativos diferentes. Cada um com um Check IF instalado, inicie-o e vá até a loja. Também não tenho controle dos domínios para carregar o arquivo de propriedade para links universais. Então, as duas opções são descartadas para mim. Precisa de uma solução javascript pura.
FranticRock
16

A partir de 2017, parece que não há uma maneira confiável de detectar que um aplicativo esteja instalado, e o truque de redirecionamento não funcionará em todos os lugares.

Para pessoas como eu, que precisam fazer o link direto diretamente de e-mails (bastante comuns), vale a pena observar o seguinte:

  • O envio de e-mails com appScheme: // não funcionará corretamente porque os links serão filtrados no Gmail

  • Redirecionar automaticamente para appScheme: // está bloqueado pelo Chrome: suspeito que o Chrome exija que o redirecionamento seja síncrono a uma interação do usuário (como um clique)

  • Agora você pode criar um link direto sem appScheme: // e é melhor, mas requer uma plataforma moderna e uma configuração adicional. Android iOS


Vale a pena notar que outras pessoas já pensaram sobre isso em profundidade. Se você observar como o Slack implementa o recurso "link mágico", você pode perceber que:

  • Ele envia um email com um link http normal (ok no Gmail)
  • A página da web possui um botão grande vinculado ao appScheme: // (ok com o Chrome)
Sebastien Lorber
fonte
9

Você pode conferir este plug-in que tenta resolver o problema. Ele é baseado na mesma abordagem descrita por missemisa e Alastair etc., mas usa um iframe oculto.

https://github.com/hampusohlsson/browser-deeplink

hampusohlsson
fonte
Adicionei isso, mas ele redireciona para a Appstore mesmo depois de instalar o aplicativo.
Qasim
9

A @Alistair apontou nesta resposta que, às vezes, os usuários retornam ao navegador após abrir o aplicativo. Um comentarista para essa resposta indicou que os valores dos tempos usados ​​precisavam ser alterados dependendo da versão do iOS. Quando nossa equipe teve que lidar com isso, descobrimos que os valores de tempo para o tempo limite inicial e informando se havíamos retornado ao navegador tinham que ser ajustados e, geralmente, não funcionavam para todos os usuários e dispositivos.

Em vez de usar um limite arbitrário de diferença de horário para determinar se retornamos ao navegador, fazia sentido detectar os eventos "ocultar página" e "exibição de página".

Desenvolvi a seguinte página da Web para ajudar a diagnosticar o que estava acontecendo. Ele adiciona diagnósticos HTML à medida que os eventos se desenrolam, principalmente porque o uso de técnicas como log do console, alertas ou Inspetor da Web, jsfiddle.net etc., todos tiveram suas desvantagens nesse fluxo de trabalho. Em vez de usar um limite de tempo, o Javascript conta o número de eventos "ocultar página" e "exibição de página" para verificar se eles ocorreram. E descobri que a estratégia mais robusta era usar um tempo limite inicial de 1000 (em vez dos 25, 50 ou 100 relatados / sugeridos por outros).

Isso pode ser servido em um servidor local, por exemplo, python -m SimpleHTTPServere exibido no iOS Safari.

Para jogar, pressione os links "Abrir um aplicativo instalado" ou "Aplicativo não instalado". Esses links devem fazer com que o aplicativo do Google Maps ou a App Store seja aberto, respectivamente. Você pode retornar ao Safari para ver a sequência e o horário dos eventos.

(Observação: isso funcionará apenas para o Safari. Para outros navegadores (como o Chrome), você precisará instalar manipuladores para os eventos ocultar páginas / mostrar equivalentes).

Atualização: Como o @Mikko apontou nos comentários, os eventos pageshow / pagehide que estamos usando aparentemente não são mais suportados no iOS8.

<html>
<head>
</head>
<body>
<a href="maps://" onclick="clickHandler()">Open an installed app</a>
<br/><br/>
<a href="xmapsx://" onclick="clickHandler()">App not installed</a>
<br/>

<script>

var hideShowCount = 0 ;
window.addEventListener("pagehide", function() {
    hideShowCount++ ;
    showEventTime('pagehide') ;
});

window.addEventListener("pageshow", function() {
    hideShowCount++ ;
    showEventTime('pageshow') ;
});

function clickHandler(){
    var hideShowCountAtClick = hideShowCount ;
    showEventTime('click') ;
    setTimeout(function () {
               showEventTime('timeout function '+(hideShowCount-hideShowCountAtClick)+' hide/show events') ;
               if (hideShowCount == hideShowCountAtClick){
                    // app is not installed, go to App Store
                    window.location = 'http://itunes.apple.com/app' ;
               }
            }, 1000);
}

function currentTime()
{
    return Date.now()/1000 ;
}

function showEventTime(event){
    var time = currentTime() ;
    document.body.appendChild(document.createElement('br'));
    document.body.appendChild(document.createTextNode(time+' '+event));
}
</script>
</body>
</html>
brainjam
fonte
2

Eu preciso fazer algo assim, acabei indo com a seguinte solução.

Eu tenho um URL de site específico que abrirá uma página com dois botões

1) Button One Ir para o site

2) Botão Dois, vá para o aplicativo (iphone / android phone / tablet), você pode voltar para um local padrão a partir daqui, se o aplicativo não estiver instalado (como outro URL ou uma loja de aplicativos)

3) cookie para lembrar a escolha dos usuários

<head>
<title>Mobile Router Example </title>


<script type="text/javascript">
    function set_cookie(name,value)
    {
       // js code to write cookie
    }
    function read_cookie(name) {
       // jsCode to read cookie
    }

    function goToApp(appLocation) {
        setTimeout(function() {
            window.location = appLocation;
              //this is a fallback if the app is not installed. Could direct to an app store or a website telling user how to get app


        }, 25);
        window.location = "custom-uri://AppShouldListenForThis";
    }

    function goToWeb(webLocation) {
        window.location = webLocation;
    }

    if (readCookie('appLinkIgnoreWeb') == 'true' ) {
        goToWeb('http://somewebsite');

    }
    else if (readCookie('appLinkIgnoreApp') == 'true') {
        goToApp('http://fallbackLocation');
    }



</script>
</head>
<body>


<div class="iphone_table_padding">
<table border="0" cellspacing="0" cellpadding="0" style="width:100%;">
    <tr>
        <td class="iphone_table_leftRight">&nbsp;</td>
        <td>
            <!-- INTRO -->
            <span class="iphone_copy_intro">Check out our new app or go to website</span>
        </td>
        <td class="iphone_table_leftRight">&nbsp;</td>
    </tr>
    <tr>
        <td class="iphone_table_leftRight">&nbsp;</td>
        <td>
            <div class="iphone_btn_padding">

                <!-- GET IPHONE APP BTN -->
                <table border="0" cellspacing="0" cellpadding="0" class="iphone_btn" onclick="set_cookie('appLinkIgnoreApp',document.getElementById('chkDontShow').checked);goToApp('http://getappfallback')">
                    <tr>
                        <td class="iphone_btn_on_left">&nbsp;</td>
                        <td class="iphone_btn_on_mid">
                            <span class="iphone_copy_btn">
                                Get The Mobile Applications
                            </span>
                        </td>
                        <td class="iphone_btn_on_right">&nbsp;</td>
                    </tr>
                </table>

            </div>
        </td>
        <td class="iphone_table_leftRight">&nbsp;</td>
    </tr>
    <tr>
        <td class="iphone_table_leftRight">&nbsp;</td>
        <td>
            <div class="iphone_btn_padding">

                <table border="0" cellspacing="0" cellpadding="0" class="iphone_btn"  onclick="set_cookie('appLinkIgnoreWeb',document.getElementById('chkDontShow').checked);goToWeb('http://www.website.com')">
                    <tr>
                        <td class="iphone_btn_left">&nbsp;</td>
                        <td class="iphone_btn_mid">
                            <span class="iphone_copy_btn">
                                Visit Website.com
                            </span>
                        </td>
                        <td class="iphone_btn_right">&nbsp;</td>
                    </tr>
                </table>

            </div>
        </td>
        <td class="iphone_table_leftRight">&nbsp;</td>
    </tr>
    <tr>
        <td class="iphone_table_leftRight">&nbsp;</td>
        <td>
            <div class="iphone_chk_padding">

                <!-- CHECK BOX -->
                <table border="0" cellspacing="0" cellpadding="0">
                    <tr>
                        <td><input type="checkbox" id="chkDontShow" /></td>
                        <td>
                            <span class="iphone_copy_chk">
                                <label for="chkDontShow">&nbsp;Don&rsquo;t show this screen again.</label>
                            </span>
                        </td>
                    </tr>
                </table>

            </div>
        </td>
        <td class="iphone_table_leftRight">&nbsp;</td>
    </tr>
</table>

</div>

</body>
</html>
nate_weldon
fonte
Eu preciso desse tipo de código para o meu requisito, mas não consigo colocar meus links. Requisito: Se o app1 estiver instalado, vá para o Link 1, ou vá para Link2. Alguém pode ajudar por favor?
SFDC_Learner
É necessário desarmar o cookie quando o aplicativo estiver instalado, caso o usuário primeiro escolha a web.
Charlie Reitzel
1

Depois de compilar algumas respostas, criei o seguinte código. O que me surpreendeu foi que o timer não fica congelado em um PC (Chrome, FF) ou Android Chrome - o gatilho funcionava em segundo plano e a verificação de visibilidade era a única informação confiável.

var timestamp             = new Date().getTime();
var timerDelay              = 5000;
var processingBuffer  = 2000;

var redirect = function(url) {
  //window.location = url;
  log('ts: ' + timestamp + '; redirecting to: ' + url);
}
var isPageHidden = function() {
    var browserSpecificProps = {hidden:1, mozHidden:1, msHidden:1, webkitHidden:1};
    for (var p in browserSpecificProps) {
        if(typeof document[p] !== "undefined"){
        return document[p];
      }
    }
    return false; // actually inconclusive, assuming not
}
var elapsedMoreTimeThanTimerSet = function(){
    var elapsed = new Date().getTime() - timestamp;
  log('elapsed: ' + elapsed);
  return timerDelay + processingBuffer < elapsed;
}
var redirectToFallbackIfBrowserStillActive = function() {
  var elapsedMore = elapsedMoreTimeThanTimerSet();
  log('hidden:' + isPageHidden() +'; time: '+ elapsedMore);
  if (isPageHidden() || elapsedMore) {
    log('not redirecting');
  }else{
    redirect('appStoreUrl');
  }
}
var log = function(msg){
    document.getElementById('log').innerHTML += msg + "<br>";
}

setTimeout(redirectToFallbackIfBrowserStillActive, timerDelay);
redirect('nativeApp://');

JS Fiddle

ptrk
fonte
-2

A solução da data é muito melhor do que outras, tive que aumentar o tempo em 50 dessa forma, este é um exemplo do Tweeter:

//on click or your event handler..
var twMessage = "Your Message to share";
var now = new Date().valueOf();
setTimeout(function () {
   if (new Date().valueOf() - now > 100) return;
   var twitterUrl = "https://twitter.com/share?text="+twMessage;
   window.open(twitterUrl, '_blank');
}, 50);
window.location = "twitter://post?message="+twMessage;

o único problema no Mobile IOS Safari é quando você não tem o aplicativo instalado no dispositivo e, portanto, o Safari mostra um alerta que ocorre automaticamente quando o novo URL é aberto, pelo menos é uma boa solução por enquanto!

Magico
fonte
1
@AkshatAgarwal porque esta é a mesma solução que a alastair postada 7 dias depois
albanx
-5

Não leu tudo isso, mas pode usar um iframe e adicionar a fonte ao "meu aplicativo: // seja qual for".

Em seguida, verifique regularmente se o intervalo definido da página é 404 ou não.

Você também pode usar a chamada Ajax. Se a resposta 404, o aplicativo não está instalado.

1,21 gigawatts
fonte
Esta solução não está funcionando.
Andrey M.