2011-09-27 16 views
16

Tengo la página web donde tengo el botón que abre la aplicación (si está instalada) o dirige a la tienda de aplicaciones si la aplicación no está instalada. Todo funciona si la aplicación está instalada (llamo a "MYAPP: //"). Sin embargo, si la aplicación no está instalada, Safari muestra el mensaje de error "No se puede abrir la URL" y eso es todo. ¿Hay alguna manera de desactivar ese mensaje de JScript o hay otra forma de averiguarlo desde JScript si la aplicación está instalada (en lugar de presionar la URL de la aplicación)?Navegador iPhone: verificando si la aplicación iPhone está instalada desde el navegador

Al MODERADOR: Vi a alguien que le preguntó similar question y el moderador lo marcó incorrectamente como duplicado. Por favor, comprenda que la pregunta fue específicamente sobre hacerlo desde el navegador.

Encontrado solución algo adecuado here

Por cierto, si alguien interesado en cómo hacer lo mismo para Android, aquí está el código. Estamos utilizando la biblioteca de Dojo:

dojo.io.iframe.send({ 
    url: "yourApp://foo/bar", 
    load: function(resp) { 
     // nothing to do since it will automagically open App 
    }, 
    error: function() { 
     window.location = "go to Android market"; 
    } 
    }); 

Respuesta

0

Creo que todavía puede usar la aplicación de la url como una prueba. Trate de envolver en un bloque try...catch,

try { 
    //run code that normally breaks the script or throws error 
} 
catch(e) { 
    //do nothing 
} 
4

aquí es un código que funciona en iOS, incluso si el "No se puede abrir URL" todavía muestran.

window.location = "yourApp://foo/bar";  
    clickedAt = +new Date; 
    setTimeout(function() { 
     if (+new Date - clickedAt < 2000) { 
      window.location = "go to Android market"; 
     } 
    }, 500); 

Gracias por la solución de Android.

+0

Aquí está un ejemplo JS completo para iOS y Android aplicación de redirección: https://gist.github.com/FokkeZB/6635236#file-all-in-one-php – Justin

0

He combinado algunas cosas y he usado el siguiente código para comprobar si se trata de un dispositivo iOS antes de utilizar el método try/catch de chazbot. Desafortunadamente, el dispositivo todavía arroja un cuadro emergente al usuario diciendo que la dirección no es válida ... ¿Alguien sabe si este es el comportamiento esperado para tratar de abrir una URL inválida dentro de un bloque "try"?

var i = 0, 
    iOS = false, 
    iDevice = ['iPad', 'iPhone', 'iPod']; 

    for (; i < iDevice.length ; i++) { 
     if(navigator.platform === iDevice[i]){ iOS = true; break; } 
    } 

    try { 
     //run code that normally breaks the script or throws error 
     if (iOS) { window.location = "myApp://open";} 
    } 
    catch(e) { 
     //do nothing 
    } 
12

En Branch se utiliza una forma del código de abajo - en cuenta que el iframe funciona en más navegadores. Simplemente sustitúyalo en el URI de su aplicación y en el enlace de la App Store. Por cierto, el uso del iframe silencia el error si no tienen la aplicación instalada. ¡Es genial!

<!DOCTYPE html> 
<html> 
    <body> 
     <script type="text/javascript"> 
      window.onload = function() { 
       // Deep link to your app goes here 
       document.getElementById("l").src = "my_app://"; 

       setTimeout(function() { 
        // Link to the App Store should go here -- only fires if deep link fails     
        window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8"; 
       }, 500); 
      }; 
     </script> 
     <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe> 
    </body> 
</html> 

Si otros tienen mejores soluciones para detectar si la llamada al esquema URI realmente falló, ¡por favor publíquela! No he visto uno, y he pasado mucho tiempo buscando. Todas las soluciones existentes solo se basan en que el usuario siga en la página y en la activación de setTimeout.

+0

Gracias, esta es la mejor solución que 'Has visto. Con todos los demás, si la aplicación de destino no está instalada, iOS 8 da un mensaje de "dirección no válida" antes de abrir la página web. Éste simplemente elige cualquier opción, y lo hace. ¡Ahora, para que funcione en Android ...! – JoLoCo

+0

buena suerte. cada navegador es diferente. intentos de Chrome vs navegador estándar vs facebook webview vs twitter webview vs pinterest. eso es lo que hago en Branch todos los días –

+0

Sí, es un verdadero campo de minas, ¡estoy descubriendo! Si tengo algún avance importante, los publicaré aquí en algún lugar ... – JoLoCo

0

Hay algunas cosas que puede hacer para mejorar otras respuestas. Desde iOS 9, se puede abrir un enlace en un UIWebView o en un SFSafariViewController. Es posible que desee manejarlos de manera diferente.

El SFSafariViewController comparte cookies entre las aplicaciones y con el Safari incorporado. Por lo tanto, en su aplicación puede realizar una solicitud a través de SFSafariViewController que establecerá una cookie que dice "mi aplicación fue instalada". Por ejemplo, abre su sitio web pidiéndole a su servidor que configure dicha cookie. Luego, cada vez que reciba una solicitud de un SFSafariViewController, puede verificar esa cookie y redirigirla al MYAPP:// si la encuentra, o a la tienda de aplicaciones si no lo hace. No es necesario abrir una página web y hacer una redirección de JavaScript, puede hacer un 301 desde su servidor. Las aplicaciones como Messages o Safari comparten esas cookies.

El UIWebView es muy complicado ya que es totalmente aislado y no se comparten cookies con ninguna otra cosa.Por lo que tendrá que vuelve a los que se ha descrito en otras respuestas:

window.onload = function() { 
    var iframe = document.createElement("iframe"); 
    var uri = 'MYAPP://'; 
    var interval = setInterval(function() { 
     // Link to the App Store should go here -- only fires if deep link fails     
     window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8"; 
    }, 500); 
    iframe.onload = function() { 
     clearInterval(interval); 
     iframe.parentNode.removeChild(iframe); 
     window.location.href = uri; 
    }; 
    iframe.src = uri; 
    iframe.setAttribute("style", "display:none;"); 
    document.body.appendChild(iframe); 
}; 

que he encontrado que es molesto que esto indicará al usuario si quieren salir de la aplicación actual (para ir a su aplicación) incluso cuando tu aplicación no está instalada. (empíricamente, eso solo parece ser verdad desde un UIWebView, si haces eso desde el Safari normal, por ejemplo, eso no sucederá) ¡pero eso es todo lo que tenemos!

Puede diferenciar el UIWebView del SFSafariViewController de su servidor, ya que tienen diferentes encabezado de agente de usuario: el SFSafariViewController contiene Safari mientras que el UIWebView no. Por ejemplo:

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E269 
-> UIWebView 

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1 
-> SFSafariViewController 

Otras consideraciones:

  • en el primer enfoque, es posible que desee para manejar las desinstalaciones: si el usuario desinstala la aplicación, todavía tiene una cookie que dice que la aplicación está allí pero no lo es, por lo que puede terminar con el mensaje "Can not open URL". Lo he manejado quitando la cookie después de algunos intentos que no terminaron abriendo la aplicación (que lo sé porque en cada aplicación abierta estoy restableciendo esta cookie de intentos fallidos)
  • En el segundo caso, no está claro si está mejor usando setInterval o setTimeout. El problema con el tiempo de espera es que si se activa mientras está activada una solicitud, se ignorará. Por ejemplo, si abres el enlace de Messenger, el sistema operativo te preguntará "¿Dejar Messenger? Estás a punto de abrir otra aplicación" cuando el iframe intente cargar tu aplicación. Si no responde de ninguna manera dentro de los 500 ms del tiempo de espera, se ignorará la redirección en el tiempo de espera.
  • Finalmente, aunque el UIWebView es un espacio aislado, puede darle una cookie para identificarlo, pasarlo en su deeplink y guardar esta identificación como correspondiente al dispositivo con su aplicación en su servidor cuando se abra su aplicación. La próxima vez, si ve dicha cookie en la solicitud proveniente del UIWebView, puede verificar si coincide con un dispositivo conocido con la aplicación y redireccionar directamente con un 301 como antes.
Cuestiones relacionadas