best browser for iphone
navegador de iPhone: verificando si la aplicación de iPhone está instalada desde el navegador (5)
Tengo una página web donde tengo un botón que abre la aplicación (si está instalada) o la dirige a App Store 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 ya está. ¿Hay alguna forma de deshabilitar ese mensaje desde JScript o hay otra forma de averiguar desde JScript si la aplicación está instalada (en lugar de golpear la URL de la aplicación)?
Para el MODERADOR: vi a alguien que hizo una pregunta similar y el Moderador lo marcó como duplicado. Por favor, comprenda que la pregunta fue específicamente sobre hacerlo desde el navegador.
Encontré una solución algo adecuada here
Por cierto, si alguien interesado en cómo hacer lo mismo para Android, aquí está el código. Estamos utilizando la biblioteca 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";
}
});
Aquí hay un código que funciona en iOs, incluso si todavía se muestra el mensaje "No se puede abrir la URL".
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.
Creo que todavía puedes usar la aplicación url como prueba. Intenta envolverlo en un bloque try...catch
,
try {
//run code that normally breaks the script or throws error
}
catch(e) {
//do nothing
}
En Branch usamos una forma del código a continuación: tenga 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 su App Store. Por cierto, el uso de 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, publique! No he visto uno, y he pasado un montón de tiempo buscando. Todas las soluciones existentes solo dependen de que el usuario aún esté en la página y de la activación de setTimeout.
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 en todas las aplicaciones y con Safari integrado. Entonces, en su aplicación, puede realizar una solicitud a través de un SFSafariViewController
que configurará una cookie que dice "mi aplicación fue instalada". Por ejemplo, usted abre su sitio web pidiéndole a su servidor que establezca dicha cookie. Luego, en cualquier momento que reciba una solicitud de un SFSafariViewController
, puede buscar esa cookie y redirigirla a MYAPP://
si la encuentra, o a la tienda de aplicaciones si no la encuentra. No es necesario abrir una página web y hacer una redirección de JavaScript, puede hacer un 301 desde su servidor. Aplicaciones como Messages
o Safari
comparten esas cookies.
El UIWebView
es muy complicado ya que está totalmente aislado y no comparte cookies con nada más. Así que tendrás que recurrir a lo 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);
};
Me ha resultado molesto que esto induzca al usuario si desea abandonar la aplicación actual (para ir a su aplicación) incluso cuando su aplicación no está instalada. (empíricamente, eso solo parece ser cierto en un UIWebView
, si lo hace desde el Safari normal, por ejemplo, eso no ocurrirá), ¡pero eso es todo lo que tenemos!
Puede diferenciar el UIWebView
del SFSafariViewController
de su servidor ya que tienen un encabezado de agente de usuario diferente: el SFSafariViewController
contiene Safari mientras que el UIWebView
no lo tiene. 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 manejar las desinstalaciones: si el usuario desinstala su aplicación, todavía tiene una cookie que dice que la aplicación está ahí pero no lo está, por lo que podría terminar con el mensaje
"Can not open URL"
. Lo he manejado eliminando la cookie después de algunos intentos que no terminaron de abrir la aplicación (lo que sé porque en cada aplicación abierta estoy restableciendo este error, intenta la cookie) - En el segundo caso, no está claro si es mejor usar un
setInterval
osetTimeout
. El problema con el tiempo de espera es que si se dispara mientras está activada una solicitud, se ignorará. Por ejemplo, si abre el enlace desde Messenger, el sistema operativo le preguntará "¿Dejar el programa? Está a punto de abrir otra aplicación" cuando el iframe intente cargar su 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
está en un espacio aislado, puede darle una cookie para identificarlo, pasarlo a su enlace y guardar esta identificación como correspondiente al dispositivo con su aplicación en su servidor cuando ésta se abra. La próxima vez, si ve una cookie de este tipo en la solicitud que proviene deUIWebView
, puede verificar si coincide con un dispositivo conocido con la aplicación y redirigir directamente con un 301 como antes.
He combinado algunas cosas y he usado el siguiente código para comprobar si es un dispositivo iOS antes de usar el método try / catch de chazbot. Desafortunadamente, el dispositivo aún muestra un cuadro emergente al usuario que dice que la dirección no es válida ... ¿Alguien sabe si se trata de un comportamiento esperado al intentar abrir una URL no válida dentro de un bloque "intentar"?
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
}