¿Cómo verificar si una aplicación está instalada desde una página web en un iPhone?

142

Quiero crear una página web, una página que redirija un iPhone a la tienda de aplicaciones si el iPhone no tiene la aplicación instalada, pero si el iPhone tiene la aplicación instalada, quiero que abra la aplicación.

Ya he implementado una url personalizada en la aplicación de iPhone, así que tengo una url para la aplicación que es algo así como:

myapp://

Y si esta URL no es válida, quiero que la página redirija a la tienda de aplicaciones. ¿Es esto posible en absoluto?

Si no tengo la aplicación instalada en el teléfono y escribo myapp: // url en safari, todo lo que obtengo es un mensaje de error.

¿Incluso si existe un truco feo con javascript que realmente me gustaría saber?

Joakim Engstrom
fuente
1
Esto sigue cambiando en cada versión de iOS: iOS9 acaba de romper todo de nuevo. Recomiendo usar un servicio como branch.io para encargarse de esto. Ayudé a construir partes del servicio de enlace Branch, y actualmente maneja más de 6000 casos de borde de redirección diferentes ... loco.
Alex Austin
1
En 2017, si su necesidad es vincular a su aplicación desde correos electrónicos, debería consultar mi respuesta: stackoverflow.com/questions/13044805/…
Sebastien Lorber

Respuestas:

198

Hasta donde sé, no puede, desde un navegador, verificar si una aplicación está instalada o no.

Pero puede intentar redirigir el teléfono a la aplicación, y si no sucede nada, redirija el teléfono a una página específica, como esta:

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

Si la segunda línea de código da un resultado, la primera fila nunca se ejecuta.

¡Espero que esto ayude!

Pregunta similar:

missemisa
fuente
20
Actualmente en iOS 6.1.2 esto parece funcionar solo en modo webapp. Si usa la aplicación directamente desde el navegador, abre la aplicación externa como se esperaba, pero el tiempo de espera también se activa y el navegador se redirige.
Mika Tuupola
44
Si la aplicación no está instalada, arroja una fea alerta de "página no encontrada". De todos modos, podemos suprimir eso
Akshat Agarwal
3
@AkshatAgarwal, ¿podría explicar cómo codificar para suprimir la 'alerta de página no encontrada'?
Harpreet
2
Hay nuevas formas de implementar esto ahora tanto en Android como en iOS. Eche un vistazo a los enlaces de aplicaciones de Android y los enlaces universales de iOS
maledr53
1
Abre la aplicación, pero también redirige el navegador a la tienda de aplicaciones / tienda de juegos. ¿Algún método / pirateo para evitar esto?
Sujeet Kumar
157

Para avanzar en la respuesta aceptada, a veces necesita agregar un código adicional para manejar a las personas que devuelven el navegador después de iniciar la aplicación, esa función setTimeout se ejecutará siempre que lo hagan. Entonces, hago algo como esto:

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://";

De esa manera, si se ha congelado la ejecución del código (es decir, el cambio de aplicación), no se ejecutará.

Alastair
fuente
2
Esta solución es mucho mejor que otras, tuve que incrementar el tiempo en 50
Magico
1
Mi comentario sobre si fallaba en iOS 7 era falso: simplemente tuve que aumentar los 100 ms a un par de segundos (de todos modos, no es necesario que sea tan corto).
devios1
En lugar de itunes.apple.com/appdir , guarde un paso (sin esperar una redirección http) y enlace directamente al esquema de URL de la tienda de aplicaciones. Por ejemplo: itms: //itunes.apple.com/us/app/yelp/id284910350
Justin
Impresionante, funciona bien para aplicaciones ios, el mismo código redirige a ambas URL al mismo tiempo en las aplicaciones de Android. ¿Qué has hecho para Android para abrir aplicaciones y Play Store?
Mehul Dudhat
66
Esto abre constantemente tanto mi aplicación como la tienda de aplicaciones, incluso a los 50. iOS 12
Josh Wolff
27

Safari de iOS tiene una función que le permite agregar un banner "inteligente" a su página web que se vinculará con su aplicación, si está instalada, o con la App Store.

Para ello, agregue una metaetiqueta a la página. Incluso puede especificar una URL de aplicación detallada si desea que la aplicación haga algo especial cuando se carga.

Los detalles están en el de Apple Promoción de Aplicaciones con Smart App Banners página.

El mecanismo tiene las ventajas de ser fácil y presentar un banner estandarizado. La desventaja es que no tienes mucho control sobre el aspecto o la ubicación. Además, todas las apuestas están desactivadas si la página se ve en un navegador que no sea Safari.

brainjam
fuente
2
Pero no muestra el banner de la aplicación si el usuario no lo ha instalado
TomSawyer
Ni los enlaces universales ni los banners inteligentes funcionan para mí. Necesito tener múltiples enlaces de aplicaciones nativas a diferentes aplicaciones. Cada uno con un Check IF instalado, inícielo, de lo contrario vaya a la tienda. Tampoco tengo control de los dominios para cargar el archivo de propiedad para enlaces universales. Por lo tanto, ambas opciones son superadas por mí. Necesita una solución javascript pura.
FranticRock
16

A partir de 2017, parece que no hay una forma confiable de detectar que una aplicación está instalada, y el truco de redireccionamiento no funcionará en todas partes.

Para aquellos como yo que necesitan un enlace profundo directamente desde correos electrónicos (bastante común), vale la pena señalar lo siguiente:

  • Enviar correos electrónicos con appScheme: // no funcionará bien porque los enlaces se filtrarán en Gmail

  • Redireccionamiento automático a appScheme: // está bloqueado por Chrome: sospecho que Chrome requiere que la redirección sea sincrónica con la interacción del usuario (como un clic)

  • Ahora puede hacer un enlace profundo sin appScheme: // y es mejor, pero requiere una plataforma moderna y una configuración adicional. Android iOS


Vale la pena señalar que otras personas ya pensaron en esto en profundidad. Si observa cómo Slack implementa su función de "enlace mágico", puede notar que:

  • Envía un correo electrónico con un enlace http regular (está bien con Gmail)
  • La página web tiene un gran botón que enlaza con appScheme: // (ok con Chrome)
Sebastien Lorber
fuente
9

Puede consultar este complemento que intenta resolver el problema. Se basa en el mismo enfoque descrito por missemisa y Alastair, etc., pero utiliza un iframe oculto.

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

hampusohlsson
fuente
Agregué esto, pero redirige a la tienda de aplicaciones incluso después de instalar la aplicación.
Qasim
9

@Alistair señaló en esta respuesta que a veces los usuarios volverán al navegador después de abrir la aplicación. Un comentarista de esa respuesta indicó que los valores de tiempos utilizados tenían que cambiarse dependiendo de la versión de iOS. Cuando nuestro equipo tuvo que lidiar con esto, descubrimos que los valores de tiempo para el tiempo de espera inicial y saber si habíamos regresado al navegador tenían que ajustarse, y a menudo no funcionaban para todos los usuarios y dispositivos.

En lugar de utilizar un umbral de diferencia de tiempo arbitrario para determinar si habíamos regresado al navegador, tenía sentido detectar los eventos de "ocultación de página" y "presentación de páginas".

Desarrollé la siguiente página web para ayudar a diagnosticar lo que estaba sucediendo. Agrega diagnósticos HTML a medida que se desarrollan los eventos, principalmente porque el uso de técnicas como el registro de la consola, las alertas o el Inspector web, jsfiddle.net, etc.todos tenían sus inconvenientes en este flujo de trabajo. En lugar de usar un umbral de tiempo, el Javascript cuenta el número de eventos de "ocultación de página" y "presentación de páginas" para ver si han ocurrido. Y descubrí que la estrategia más sólida era usar un tiempo de espera inicial de 1000 (en lugar de los 25, 50 o 100 reportados / sugeridos por otros).

Esto se puede servir en un servidor local, por ejemplo, python -m SimpleHTTPServery se puede ver en iOS Safari.

Para jugar con él, presione los enlaces "Abrir una aplicación instalada" o "Aplicación no instalada". Estos enlaces deberían hacer que se abran respectivamente la aplicación Mapas o la App Store. Luego puede regresar a Safari para ver la secuencia y el momento de los eventos.

(Nota: esto solo funcionará para Safari. Para otros navegadores (como Chrome), tendrías que instalar controladores para los eventos equivalentes a mostrar / mostrar páginas).

Actualización: como @Mikko ha señalado en los comentarios, los eventos de presentación de página / ocultación de página que estamos usando aparentemente ya no son compatibles con 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
fuente
2

Necesito hacer algo como esto, terminé yendo con la siguiente solución.

Tengo una URL de sitio web específica que abrirá una página con dos botones

1) Botón uno ir al sitio web

2) El botón dos va a la aplicación (iPhone / teléfono / tableta Android), puede volver a una ubicación predeterminada desde aquí si la aplicación no está instalada (como otra url o una tienda de aplicaciones)

3) cookie para recordar la elección de los usuarios

<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
fuente
Necesito este tipo de código para mis requisitos pero no puedo colocar mis enlaces. Requisito: si la aplicación1 está instalada, vaya al Enlace 1, de lo contrario, vaya a Enlace2. ¿Puede ayudarme alguien, por favor?
SFDC_Learner
Es necesario desactivar la cookie cuando se instala la aplicación, en caso de que el usuario primero elija la web.
Charlie Reitzel
1

Después de compilar algunas respuestas, se me ocurrió el siguiente código. Lo que me sorprendió fue que el temporizador no se congela en una PC (Chrome, FF) o Android Chrome: el disparador funcionó en segundo plano y la verificación de visibilidad fue la única información confiable.

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
fuente
-2

La solución de la fecha es mucho mejor que otras, tuve que incrementar el tiempo en 50 así, este es un ejemplo de 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;

El único problema en Mobile IOS Safari es cuando no tienes la aplicación instalada en el dispositivo, y Safari muestra una alerta de que el auto desecho cuando se abre la nueva URL, ¡de todos modos es una buena solución por ahora!

Magico
fuente
1
@AkshatAgarwal porque esta es la misma solución que
Alastair One
-5

No leí todo esto, pero puede usar un iframe y agregar la fuente a "mi aplicación: // lo que sea".

Luego verifique regularmente si el intervalo establecido de la página es 404 o no.

También puede usar la llamada Ajax. Si la respuesta 404, entonces la aplicación no está instalada.

1,21 gigavatios
fuente
Esta solución no funciona.
Andrey M.