Ci sono alcune cose che puoi fare per migliorare altre risposte. Da iOS 9, un collegamento può essere aperto in un UIWebView
o in un SFSafariViewController
. Potresti volerli trattare in modo diverso.
Il SFSafariViewController
condivide i cookie tra le app e con Safari integrato. Quindi nella tua app puoi fare una richiesta tramite un SFSafariViewController
che imposterà un cookie che dice "la mia app è stata installata". Ad esempio, apri il tuo sito web chiedendo al tuo server di impostare tale cookie. Quindi, ogni volta che ricevi una richiesta da un SFSafariViewController
puoi controllare quel cookie e reindirizzare a MYAPP://
se lo trovi, o all'app store se non lo fai. Non c'è bisogno di aprire una pagina web e fare un reindirizzamento javascript, puoi fare un 301 dal tuo server. App come Messages
o Safari
condividono questi cookie.
Il UIWebView
è molto difficile poiché è totalmente in modalità sandbox e non ha condiviso cookie con nient'altro.Così avrete il fallback su quello che è stato descritto in altre risposte:
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);
};
ho trovato fastidioso che questo richiederà all'utente se vogliono lasciare l'applicazione corrente (per andare alla tua app) anche quando la tua app non è installata. (empiricamente sembra vero solo da un UIWebView
, se lo fai dal normale Safari per esempio che non succederà) ma questo è tutto ciò che abbiamo!
È possibile distinguere il UIWebView
dal SFSafariViewController
dal server in quanto hanno diversa intestazione user agent: il SFSafariViewController
contiene Safari mentre il UIWebView
non lo fa. Per esempio:
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
Altre considerazioni:
- nel primo approccio, si potrebbe desiderare di gestire disinstallazioni: se l'utente disinstalla la vostra applicazione, avete ancora un cookie che dice che l'applicazione è lì ma non lo è, quindi potresti finire con il messaggio
"Can not open URL"
. L'ho gestito rimuovendo il cookie dopo alcuni tentativi che non hanno finito per aprire l'app (che so perché ad ogni app aperta sto ripristinando questo cookie fallito)
- Nel secondo caso, non è chiaro se stai meglio usando un
setInterval
o setTimeout
. Il problema con il timeout è che se si attiva quando un prompt è attivo, verrà ignorato. Ad esempio se apri il link da Messenger, il sistema operativo ti chiederà "Invia Messenger? Stai per aprire un'altra app" quando l'iframe prova a caricare la tua app. Se non rispondi in entrambi i modi entro i 500 ms del timeout, il reindirizzamento nel timeout verrà ignorato.
- Infine, anche se lo
UIWebView
è in modalità sandbox, puoi assegnargli un cookie per identificarlo, passarlo nel tuo deeplink e salvare questo ID come corrispondente al dispositivo con la tua app sul tuo server all'apertura della tua app. La prossima volta, se visualizzi tale cookie nella richiesta proveniente dallo UIWebView
, puoi verificare se corrisponde a un dispositivo noto con l'app e reindirizzare direttamente con un 301 come in precedenza.
Ecco un esempio JS completa per iOS e Android reindirizzamento: https://gist.github.com/FokkeZB/6635236#file-all-in-one-php – Justin