2011-09-27 10 views
16

Ho una pagina Web in cui ho Button che apre l'app (se installata) o indirizza all'App store se l'app non è installata. Funziona tutto se è installata l'app (chiamo in "MYAPP: //"). Tuttavia, se l'app non è installata, Safari mostra un messaggio di errore "Impossibile aprire l'URL" e il gioco è fatto. C'è un modo per disabilitare quel messaggio da JScript o c'è un altro modo per scoprirlo da JScript se l'app è installata (invece di colpire l'URL dell'app)?Browser iPhone: Verifica se l'app per iPhone è installata dal browser

A MODERATORE: ho visto che qualcuno ha chiesto similar question e il moderatore lo ha contrassegnato erroneamente come duplicato. Ti preghiamo di comprendere che la domanda riguardava specificamente il fatto di eseguirla dal browser.

Trovato soluzione un po 'adatto here

BTW se qualcuno interessato a come fare stessa cosa per Android, qui è il codice. Stiamo utilizzando la libreria 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"; 
    } 
    }); 

risposta

0

Penso che tu possa ancora utilizzare l'URL dell'app come test. Prova avvolgendolo in un blocco try...catch,

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

ecco un codice che funziona su iOS, anche se il "Impossibile aprire URL" mostrano ancora.

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

Grazie per la soluzione Android.

+0

Ecco un esempio JS completa per iOS e Android reindirizzamento: https://gist.github.com/FokkeZB/6635236#file-all-in-one-php – Justin

0

Ho combinato alcune cose e ho usato il seguente codice per verificare se si tratta di un dispositivo iOS prima di utilizzare il metodo try/catch da chazbot. Sfortunatamente, il dispositivo getta ancora una finestra pop-up all'utente dicendo che l'indirizzo non è valido ... qualcuno sa se questo è un comportamento previsto per tentare di aprire un URL non valido all'interno di un blocco "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

A Branch usiamo una forma del codice qui sotto - si noti che l'iframe funziona su più browser. Semplicemente sostituisci l'URI della tua app e il tuo link all'App Store. A proposito, usare l'iframe fa tacere l'errore se non hanno l'app installata. È ottimo!

<!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> 

Se altri hanno soluzioni migliori per rilevare se la chiamata dello schema URI effettivamente fallita, si prega di inviare! Non ne ho visto uno, e ho passato un sacco di tempo a cercare. Tutte le soluzioni esistenti si basano solo sull'utente ancora presente sulla pagina e sull'attivazione di setTimeout.

+0

Grazie, questa è la soluzione migliore che ho 'ho visto. Con tutti gli altri, se l'app di destinazione non è installata, iOS 8 fornisce un messaggio "indirizzo non valido" prima di aprire la pagina web. Questo sceglie solo l'opzione, e lo fa. Ora, per farlo funzionare su Android ..! – JoLoCo

+0

buona fortuna. ogni browser è diverso intenti chrome vs browser standard vs facebook webview vs twitter webview vs pinterest. questo è quello che faccio al Branch ogni giorno –

+0

Sì, è un vero campo minato, sto scoprendo! Se avrò delle scoperte importanti, le posterò qui da qualche parte ... – JoLoCo

0

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.
Problemi correlati