È possibile registrare uno schema URL basato sul dominio http + per le app per iPhone, come YouTube e Maps?


223

Mi piacerebbe avere iOS per aprire gli URL dal mio dominio (ad esempio http://martijnthe.nl ) con la mia app ogni volta che l'app è installata sul telefono e con Mobile Safari nel caso non lo fosse.

Ho letto che è possibile creare un suffisso di protocollo univoco per questo e registrarlo in Info.plist, ma Mobile Safari genererà un errore nel caso in cui l'app non sia installata.

Quale sarebbe una soluzione alternativa?

Un'idea:

1) Utilizzare gli URL http: // che si aprono in qualsiasi browser desktop e rendono il servizio tramite il browser

2) Controlla l'Utente-Agente e, nel caso in cui sia Mobile Safari, apri un myprotocol: // URL a (tenta) di aprire l'app per iPhone e fallo aprire iTunes per dispositivi mobili al download dell'app nel caso in cui il tentativo fallisca

Non sei sicuro che funzionerà ... suggerimenti? Grazie!


4
Nella metropolitana di New York, c'è il wifi di Boingo che ti fornisce l'accesso gratuito al WiFi se scarichi un'applicazione che loro raccomandano. Una volta scaricato, si torna a Safari e il browser rileva se è stato installato e quindi concede l'accesso. Qualche idea su come sia stato fatto?
TommyG,

2
Universal Links ora supporterebbe questo caso d'uso senza alcun messaggio di errore. Ecco come configurare il tuo dominio e la tua app: blog.branch.io/…
Alex Austin,

Risposte:


243

Penso che il modo meno invadente per farlo sia il seguente:

  1. Controlla se l'agente utente è quello di un iPhone / iPod Touch
  2. Controlla un appInstalled cookie
  3. Se il cookie esiste ed è impostato su true, impostare window.locationsuyour-uri:// (o reindirizzare il lato server)
  4. Se il cookie non esiste, apri un "Lo sapevi che il nome del tuo sito ha un'applicazione iPhone?" modale con un "Sì, l'ho già capito", "No, ma mi piacerebbe provarlo" e il pulsante "Lasciami in pace".
    1. Il pulsante "Sì" imposta il cookie su true e reindirizza a your-uri://
    2. Il pulsante "No" reindirizza a " http://itunes.com/apps/yourappname " che aprirà l'App Store sul dispositivo
    3. Il pulsante "Lasciami in pace" imposta il cookie su false e chiude il modale

L'altra opzione con cui ho giocato ma che ho trovato un po 'goffa era quella di eseguire le seguenti operazioni in Javascript:

setTimeout(function() {
  window.location = "http://itunes.com/apps/yourappname";
}, 25);

// If "custom-uri://" is registered the app will launch immediately and your
// timer won't fire. If it's not set, you'll get an ugly "Cannot Open Page"
// dialogue prior to the App Store application launching
window.location = "custom-uri://";

16
Ottima soluzione Se il fallback è su un'altra applicazione, verrà caricato IMMEDIATAMENTE senza visualizzare l'errore. Quindi, invece di tornare su itunes.com ... usa itms: //phobos.apple.com / ... per evitare l'errore popup!
jb.

47
Problema : in caso di window.location="custom-uri://successo, il timeout di fallback non viene interrotto. Quando l'utente torna al browser dalla tua app, il timer è ancora lì e avvierà il link dell'app store. Questa è un'esperienza utente scadente.
JoJo

5
Sembra che i cookie siano in modalità sandbox in # ios6, quindi non è possibile accedere ai cookie impostati da un'applicazione da un'altra. (App WebUI e Safari Mobile per esempio)
Olivier Amblet

2
Qualcuno trova un modo per impedire l'attivazione del timeout originale quando l'utente torna al browser? (il problema sollevato menzionato da JoJo)
cobolstinks

2
Per risolvere il problema menzionato da JoJo, esegui il codice nel timeout solo se non è trascorso "molto tempo" da quando l'utente ha fatto clic sul collegamento. Vedere questa soluzione: stackoverflow.com/a/14751543/533420
kkara

95

È possibile farlo in JavaScript purché il fallback sia un altro applink. Basandosi sul suggerimento di Nathan :

<html>
  <head>
    <meta name="viewport" content="width=device-width" />
  </head>
  <body>

    <h2><a id="applink1" href="fb://profile/116201417">open facebook with fallback to appstore</a></h2>
    <h2><a id="applink2" href="unknown://nowhere">open unknown with fallback to appstore</a></h2>
    <p><i>Only works on iPhone!</i></p>    

  <script type="text/javascript">

// To avoid the "protocol not supported" alert, fail must open another app.
var appstorefail = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6";

function applink(fail){
    return function(){
        var clickedAt = +new Date;
        // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
        setTimeout(function(){
            // To avoid failing on return to MobileSafari, ensure freshness!
            if (+new Date - clickedAt < 2000){
                window.location = fail;
            }
        }, 500);    
    };
}

document.getElementById("applink1").onclick = applink(appstorefail);
document.getElementById("applink2").onclick = applink(appstorefail);

</script>
</body>
</html>

Guarda una demo live qui .


7
D'accordo con Lee, questa sembra una soluzione più semplice, anche se continuo a ricevere il messaggio di errore da Safari se l'app non esiste e reindirizza all'app store.
Jon,

2
Ho usato questa soluzione sia per Android che per iOS. Ho scoperto che se cambio il valore di timeout da 500 a 100 non visualizzo la finestra di dialogo popup "Impossibile aprire la pagina" in iOS. Ho anche scoperto che il timeout deve essere 50 per Android
Rossini dal

14
Usando "itms-apps:" invece di "itms:" salva 1 reindirizzamento e apre direttamente la pagina dell'app nell'app store.
Latorre tedesco,

6
@Rossini questo è integrato in Android impostando un filtro intenti per la tua azione che risponde a un determinato host
jwadsack,

9
Qualcuno sa come evitare il messaggio di errore "impossibile aprire la pagina" da Safari se l'app non è installata e prima di reindirizzare all'app store?
davidk,


24

Ho scoperto che la risposta selezionata funziona per le app del browser ma avevo problemi con il codice che funzionava in app non del browser che implementavano un UIWebView .

Il problema per me era che un utente dell'app Twitter avrebbe fatto clic su un collegamento che li avrebbe portati sul mio sito tramite UIWebViewl'app Twitter. Quindi, quando hanno fatto clic su un pulsante dal mio sito, Twitter cerca di essere elegante e completa solo window.locationse il sito è raggiungibile. Quindi, ciò che accade è un UIAlertViewpop-up che dice che sei sicuro di voler continuare e quindi reindirizzare immediatamente all'App Store senza un secondo popup.

La mia soluzione prevede iframe. Questo evita di UIAlertViewessere presentato consentendo un'esperienza utente semplice ed elegante.

jQuery

var redirect = function (location) {
    $('body').append($('<iframe></iframe>').attr('src', location).css({
        width: 1,
        height: 1,
        position: 'absolute',
        top: 0,
        left: 0
    }));
};

setTimeout(function () {
    redirect('http://itunes.apple.com/app/id');
}, 25);

redirect('custom-uri://');

Javascript

var redirect = function (location) {
    var iframe = document.createElement('iframe');
    iframe.setAttribute('src', location);
    iframe.setAttribute('width', '1px');
    iframe.setAttribute('height', '1px');
    iframe.setAttribute('position', 'absolute');
    iframe.setAttribute('top', '0');
    iframe.setAttribute('left', '0');
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null;
};

setTimeout(function () {
    redirect('http://itunes.apple.com/app/id');
}, 25);

redirect('custom-uri://');

MODIFICARE:

Aggiungi la posizione assoluta all'iframe, quindi quando inserito non c'è un po 'di spazio bianco casuale nella parte inferiore della pagina.

Inoltre, è importante notare che non ho riscontrato la necessità di questo approccio con Android. L'uso window.location.hrefdovrebbe funzionare bene.


1
Funziona!! Grazie ho finalmente trovato una soluzione che funziona su tutti i browser.
Koleror,

2
Questa è la soluzione migliore se trovata. Grazie. Non ci sono più popup di errori.
Confile

1
@Tim se si desidera che questo codice venga attivato quando si fa clic su un collegamento, quindi avvolgere questo codice in una funzione che viene chiamata dopo aver fatto clic sul collegamento.
cnotethegr8,

1
@ cnotethegr8 L'ho messo in una funzione e il reindirizzamento all'URL personalizzato funziona benissimo, ma il fallback su iTunes no. Ecco il mio codice . Cosa mi sto perdendo?
Tim

1
Qualcun altro ha avuto problemi con questo in iOS 9. Non funziona più per me in Safari.
bgolson,

20

In iOS9 Apple ha finalmente introdotto la possibilità di registrare la tua app per gestire determinati http://URL: Universal Links .

Una spiegazione molto approssimativa di come funziona:

  • Dichiari interesse ad aprire gli http://URL per determinati domini (URL web) nella tua app.
  • Sul server dei domini specificati devi indicare quali URL aprire in quale app ha dichiarato interesse ad aprire gli URL dal dominio del server.
  • Il servizio di caricamento degli URL iOS controlla tutti i tentativi di apertura degli http://URL per un'installazione come spiegato sopra e apre automaticamente l'app corretta se installata; senza passare prima attraverso Safari ...

Questo è il modo più pulito per fare deep linking su iOS, purtroppo funziona solo su iOS9 e versioni successive ...


e non funziona all'interno del browser ... solo all'esterno, come da imessage o note
Mihey Mik

9

EDILIZIA Ancora sulla risposta di Nathan e JB:

Come avviare l'app dall'URL senza fare clic extra Se si preferisce una soluzione che non include il passaggio intermedio del clic su un collegamento, è possibile utilizzare quanto segue. Con questo javascript, sono stato in grado di restituire un oggetto Httpresponse da Django / Python che avvia correttamente un'app se è installata o in alternativa avvia l'app store in caso di timeout. Nota: ho anche bisogno di regolare il periodo di timeout da 500 a 100 affinché questo funzioni su un iPhone 4S. Prova e ottimizza per ottenere la soluzione giusta per la tua situazione.

<html>
<head>
   <meta name="viewport" content="width=device-width" />
</head>
<body>

<script type="text/javascript">

// To avoid the "protocol not supported" alert, fail must open another app.
var appstorefail = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6";

var loadedAt = +new Date;
setTimeout(
  function(){
    if (+new Date - loadedAt < 2000){
      window.location = appstorefail;
    }
  }
,100);

function LaunchApp(){
  window.open("unknown://nowhere","_self");
};
LaunchApp()
</script>
</body>
</html>

9
window.location = appurl;// fb://method/call..
!window.document.webkitHidden && setTimeout(function () {
    setTimeout(function () {
    window.location = weburl; // http://itunes.apple.com/..
    }, 100);
}, 600);

document.webkitHidden è rilevare se la tua app è già invocata e la scheda Safari corrente passa in background, questo codice proviene da www.baidu.com


Ho testato questa soluzione e ho scoperto che, mentre consegna correttamente gli eventi, appare momentaneamente la finestra di dialogo "Impossibile aprire questa pagina perché l'indirizzo non è valido". (Si elimina automaticamente dopo una frazione di secondo).
michaelhanson,

usa un iframe per caricare appurle weburlpotrebbe risolvere il tuo problema
zyanlu,

1
@zyanlu: ho provato con iFrame. ma ancora safari sta mostrando lo stesso errore.
Kunjus,

5

Se aggiungi un elemento iframesulla tua pagina web con l' srcimpostazione su schema personalizzato per la tua app, iOS reindirizzerà automaticamente a quella posizione nell'app. Se l'app non è installata, non succederà nulla. Ciò consente di collegarsi in profondità all'app se è installata o di reindirizzare all'App Store se non è installata.

Ad esempio, se hai installato l'app di Twitter e accedi a una pagina web contenente il seguente markup, verrai immediatamente indirizzato all'app.

<!DOCTYPE html>
<html>
    <head>
    <title>iOS Automatic Deep Linking</title>
    </head>
    <body>
        <iframe src="twitter://" width="0" height="0"></iframe>
        <p>Website content.</p>
    </body>
</html>

Ecco un esempio più completo che reindirizza all'App Store se l'app non è installata:

<!DOCTYPE html>
<html>
    <head>
    <title>iOS Automatic Deep Linking</title>
    <script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
    <script src='//mobileesp.googlecode.com/svn/JavaScript/mdetect.js'></script>
    <script>
      (function ($, MobileEsp) {
        // On document ready, redirect to the App on the App store.
        $(function () {
          if (typeof MobileEsp.DetectIos !== 'undefined' && MobileEsp.DetectIos()) {
            // Add an iframe to twitter://, and then an iframe for the app store
            // link. If the first fails to redirect to the Twitter app, the
            // second will redirect to the app on the App Store. We use jQuery
            // to add this after the document is fully loaded, so if the user
            // comes back to the browser, they see the content they expect.
            $('body').append('<iframe class="twitter-detect" src="twitter://" />')
              .append('<iframe class="twitter-detect" src="itms-apps://itunes.com/apps/twitter" />');
          }
        });
      })(jQuery, MobileEsp);
    </script>
    <style type="text/css">
      .twitter-detect {
        display: none;
      }
    </style>
    </head>
    <body>
    <p>Website content.</p>
    </body>
</html>

Il problema con il tuo primo esempio è che se torni a Mobile Safari, verrà visualizzato "L'app di Twitter non è installata" anche se Twitter è stato avviato. Lo stesso con il secondo esempio, visualizzando "Contenuto del sito Web". È necessario un codice che esegua operazioni diverse (carica un altro URL o visualizza uno dei due messaggi) se l'app è installata.
Mahboudz,

1
Sì, @mahboudz, se leggi il testo, è solo un semplice esempio per mostrare che è possibile reindirizzare automaticamente all'app.
q0rban

Seguo quindi un esempio più approfondito che mostrerebbe il contenuto effettivo del sito Web. Posso eliminare il testo "L'app di Twitter non è installata" se lo renderà più chiaro.
q0rban

iOS 6 visualizza ancora il popup Quella pagina non può essere aperta a causa
dell'URL

@AndreiShender, ecco le statistiche sull'utilizzo di iOS al momento della stesura di questo documento: monosnap.com/image/8eXUcpEUi8fm94DiMZIdiIp4xUNaln.png iOS 8: 72%, iOS 7: 25%, Versioni precedenti: 3%
q0rban

4

Ecco una soluzione.

Imposta una sitiazione booleana usando sfocatura e messa a fuoco

//see if our window is active
window.isActive = true;
$(window).focus(function() { this.isActive = true; });
$(window).blur(function() { this.isActive = false; });

Associa il tuo link a un gestore di clic jquery che chiama qualcosa del genere.

function startMyApp(){
  document.location = 'fb://';

  setTimeout( function(){
    if (window.isActive) {
        document.location = 'http://facebook.com';
    }
  }, 1000);
}

se l'app si apre, perderemo la concentrazione sulla finestra e il timer scade. altrimenti non otteniamo nulla e carichiamo il solito URL di Facebook.


Grazie mille per il suggerimento. Sto affrontando il problema che il dialogo "Avvia applicazione esterna" sembra essere sufficiente per la sfocatura per inattivare la bandiera. Ciò accade anche se l'app non è installata (ad esempio, quando si fa clic su un collegamento per avviare un'app per iPhone su un desktop). Idee?
Fluxon

2

Per quanto ne so, non è possibile far comprendere all'intero SO un http:URL di dominio +. Puoi registrare solo nuovi schemi (che uso x-darkslide:nella mia app). Se l'app è installata, Mobile Safari avvierà l'app correttamente.

Tuttavia, dovresti gestire il caso in cui l'app non è installata con un "Ancora qui? Fai clic su questo link per scaricare l'app da iTunes." nella tua pagina web.


2
Questo non è più corretto: con iOS9 e versioni recenti di Android puoi registrare la tua app per ascoltare determinati httpURL
severin

0

Controlla l'Utente-Agente e, nel caso in cui sia Mobile Safari, apri un myprotocol: // URL a (tenta) di aprire l'app per iPhone e fallo aprire iTunes per dispositivi mobili al download dell'app nel caso in cui il tentativo fallisca

Mi sembra un approccio ragionevole, ma non credo che riuscirai ad aprirlo su iTunes mobile come seconda risorsa. Penso che dovrai scegliere l'uno o l'altro, o reindirizzare alla tua app o su iTunes.

cioè se reindirizzi a myprotocol: // e l'app non è al telefono, non avrai una seconda possibilità di reindirizzare su iTunes.

Potresti forse prima reindirizzare a una pagina di destinazione (ottimizzata per iPhone) e dare all'utente la possibilità di fare clic sulla tua app o su iTunes per ottenere l'app se non ce l'hanno? Ma farai affidamento sull'utente per fare la cosa giusta lì. (Modifica: anche se potresti impostare un cookie in modo che sia solo una prima volta?)


1
È sbagliato. Se viene visualizzato un errore che non è possibile aprire la pagina (App non installata), JS viene comunque eseguito. Ecco perché è possibile reindirizzare a un'altra soluzione di fallback.
Erik,

0

Nel tentativo di risolvere il problema del pop-up, ho scoperto che Apple ha risolto questo problema.

Infatti, quando si fa clic su questo collegamento , se è stata installata l'applicazione, viene reindirizzata ad essa; in caso contrario, verrai reindirizzato alla pagina Web, senza alcun popup.


3
Ho approfondito il funzionamento di quel link e il meglio che posso trovare è che non si tratta affatto di una soluzione JavaScript. Apple sembra aver registrato un gestore URL speciale per la propria app che non richiede un protocollo personalizzato ed è invece un po 'corrispondente su una stringa URL. Il link che invii reindirizza immediatamente con un 303 a qui . Se invii quel link in una email a te stesso puoi osservare che facendo clic su di esso si aprirà direttamente l'app AppStore se installata
Casey

Molto interessante. Hai ragione: se faccio clic su di essa, viene visualizzata l'app AppStore se installata. Ma se elimini alcuni parametri fino a "giorni festivi", viene visualizzato in Safari. Apple può registrare uno schema URL speciale ...
Titoli

@Titignes, potresti per favore approfondire in questo modo per aprire l'app o la pagina web. Qual è lo schema per la creazione di un tale URL?
Andrei Shender,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.