Ist es möglich, ein http + Domain-basiertes URL-Schema für iPhone-Apps wie YouTube und Maps zu registrieren?

223

Ich möchte, dass iOS URLs aus meiner Domain (z. B. http://martijnthe.nl ) mit meiner App öffnet, wenn die App auf dem Telefon installiert ist, und mit Mobile Safari, falls dies nicht der Fall ist.

Ich habe gelesen, dass es möglich ist, ein eindeutiges Protokollsuffix dafür zu erstellen und es in der Info.plist zu registrieren, aber Mobile Safari gibt einen Fehler aus, falls die App nicht installiert ist.

Was wäre eine Problemumgehung?

Eine Idee:

1) Verwenden Sie http: // URLs, die in einem beliebigen Desktop-Browser geöffnet werden, und rendern Sie den Dienst über den Browser

2) Überprüfen Sie den User-Agent und öffnen Sie für den Fall, dass es sich um Mobile Safari handelt, ein myprotocol: // URL, um die iPhone-App zu öffnen (versuchen) und Mobile iTunes zum Herunterladen der App zu öffnen, falls der Versuch fehlschlägt

Nicht sicher, ob dies funktionieren wird ... Vorschläge? Vielen Dank!

Martijn Thé
quelle
4
In der U-Bahn von NYC gibt es WLAN von Boingo, mit dem Sie kostenlos auf WLAN zugreifen können, wenn Sie eine von ihnen empfohlene Anwendung herunterladen. Sobald Sie es heruntergeladen haben, kehren Sie zu Safari zurück und der Browser erkennt, ob es installiert wurde, und gewährt Ihnen dann Zugriff. Irgendeine Idee, wie das gemacht wird?
TommyG
2
Universal Links würde diesen Anwendungsfall jetzt ohne Fehlermeldung unterstützen. So konfigurieren Sie Ihre Domain und App: blog.branch.io/…
Alex Austin

Antworten:

243

Ich denke, der am wenigsten aufdringliche Weg, dies zu tun, ist wie folgt:

  1. Überprüfen Sie, ob der Benutzeragent der eines iPhone / iPod Touch ist
  2. Suchen Sie nach einem appInstalled Cookie
  3. Wenn das Cookie vorhanden und auf true gesetzt ist, setzen Sie es window.locationaufyour-uri:// (oder führen Sie die Umleitungsserverseite aus).
  4. Wenn das Cookie nicht vorhanden ist, öffnen Sie ein "Wussten Sie, dass Ihr Site-Name eine iPhone-Anwendung hat?" modal mit einem "Ja, ich habe es schon", "Nein, aber ich würde es gerne versuchen" und "Lass mich in Ruhe" -Button.
    1. Die Schaltfläche "Ja" setzt den Cookie auf "wahr" und leitet ihn weiter your-uri://
    2. Die Schaltfläche "Nein" leitet zu " http://itunes.com/apps/yourappname " weiter, wodurch der App Store auf dem Gerät geöffnet wird
    3. Die Schaltfläche "Lass mich in Ruhe" setzt den Cookie auf "false" und schließt das Modal

Die andere Option, mit der ich gespielt habe, die ich aber als etwas klobig empfunden habe, war, in Javascript Folgendes zu tun:

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://";
Nathan de Vries
quelle
16
Tolle Lösung. Wenn Sie auf eine andere Anwendung zurückgreifen , wird diese SOFORT geladen, ohne dass der Fehler angezeigt wird. Anstatt auf itunes.com zurückzugreifen, verwenden Sie itms: //phobos.apple.com / ..., um den Popup-Fehler zu vermeiden!
jb.
47
Problem : Wenn dies window.location="custom-uri://erfolgreich ist, wird das Fallback-Timeout nicht beendet. Wenn der Benutzer von Ihrer App zum Browser zurückkehrt, ist der Timer noch vorhanden und startet den App Store-Link. Dies ist eine schlechte Benutzererfahrung.
JoJo
5
Es scheint, dass die Cookies in # ios6 in einer Sandbox gespeichert sind, sodass Sie nicht auf Cookies zugreifen können, die von einer Anwendung einer anderen Anwendung erstellt wurden. (App WebUI und Safari Mobile zum Beispiel)
Olivier Amblet
2
Hat jemand einen Weg gefunden, um zu verhindern, dass das ursprüngliche Timeout ausgelöst wird, wenn der Benutzer zum Browser zurückkehrt? (das aufgewertete Problem, das JoJo erwähnt)
Cobolstinks
2
Um das von JoJo erwähnte Problem zu lösen, führen Sie den Code nur im Timeout aus, wenn nicht "viel Zeit" vergangen ist, seit der Benutzer auf den Link geklickt hat. Siehe diese Lösung: stackoverflow.com/a/14751543/533420
kkara
95

Es ist durchaus möglich, dies in JavaScript zu tun, solange Ihr Fallback eine andere Anwendung ist. Aufbauend auf Nathans Vorschlag :

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

Schauen Sie sich hier eine Live-Demo an .

jb.
quelle
7
Ich stimme Lee zu, dies scheint eine einfachere Lösung zu sein - obwohl ich immer noch die Fehlermeldung von Safari erhalte, wenn die App nicht existiert und sie zum App Store weiterleitet.
Jon
2
Ich habe diese Lösung sowohl für Android als auch für iOS verwendet. Wenn ich den Timeout-Wert von 500 auf 100 ändere, wird unter iOS das Popup-Dialogfeld "Seite kann nicht geöffnet werden" angezeigt. Ich fand auch, dass das Timeout 50 für Android sein muss
Rossini
14
Die Verwendung von "itms-apps:" anstelle von "itms:" speichert 1 Weiterleitung und öffnet die App-Seite direkt im Appstore.
Deutscher Latorre
6
@ Rossini Dies ist in Android integriert, indem ein Absichtsfilter für Ihre Aktion eingerichtet wird, der auf einen bestimmten Host reagiert
jwadsack
9
Weiß jemand, wie die Fehlermeldung "Seite kann nicht geöffnet werden" von Safari vermieden werden kann, wenn die App nicht installiert ist und bevor sie zum App Store weitergeleitet wird?
Davidk
26

Für iOS 6-Geräte gibt es eine Option: Heraufstufen von Apps mit Smart App-Bannern

Oh ho
quelle
12
Leider werden Smart App Banner nur in Mobile Safari unterstützt, nicht in UIWebviewComponent. Es wird also nicht angezeigt, wenn Ihre Website beispielsweise in einem Twitter-Client angezeigt wird.
Olivier Amblet
24

Ich habe festgestellt, dass die ausgewählte Antwort für die Browser-Apps funktioniert, aber ich hatte Probleme mit dem Code, der in Nicht-Browser-Apps funktioniert, die a implementieren UIWebView .

Das Problem für mich war, dass ein Benutzer in der Twitter-App auf einen Link klickte, der ihn über eine UIWebViewin der Twitter-App zu meiner Website führte . Wenn sie dann auf eine Schaltfläche auf meiner Website klicken, versucht Twitter, ausgefallen zu sein und das nur zu vervollständigen, window.locationwenn die Website erreichbar ist. Was also passiert, ist aUIAlertView Popup-Fenster, das besagt, dass Sie sicher sind, dass Sie fortfahren möchten, und dann ohne ein zweites Popup sofort zum App Store weiterleitet.

Meine Lösung beinhaltet Iframes. Dies vermeidet dasUIAlertView Präsentation und ermöglicht eine einfache und elegante Benutzererfahrung.

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://');

BEARBEITEN:

Fügen Sie dem Iframe die absolute Position hinzu, damit beim Einfügen kein zufälliges Leerzeichen am unteren Rand der Seite angezeigt wird.

Es ist auch wichtig zu beachten, dass ich mit Android keinen Bedarf für diesen Ansatz gefunden habe. Die Verwendung window.location.hrefsollte gut funktionieren.

cnotethegr8
quelle
1
Es klappt!! Danke, ich habe endlich eine Lösung gefunden, die auf jedem Browser funktioniert.
Koleror
2
Dies ist die beste Lösung, wenn gefunden. Danke dir. Es gibt kein Fehler-Popup mehr.
Confile
1
@Tim Wenn Sie möchten, dass dieser Code beim Klicken auf einen Link ausgelöst wird, schließen Sie diesen Code in eine Funktion ein, die aufgerufen wird, sobald auf den Link geklickt wird.
cnotethegr8
1
@ cnotethegr8 Ich habe es in eine Funktion eingefügt und die Weiterleitung zu einer benutzerdefinierten URL funktioniert hervorragend, aber das Zurückgreifen auf iTunes funktioniert nicht. Hier ist mein Code . Was vermisse ich?
Tim
1
Hat jemand anderes Probleme damit in iOS 9. Es funktioniert nicht mehr für mich in Safari.
Bgolson
20

In iOS9 hat Apple endlich die Möglichkeit eingeführt, Ihre App für bestimmte http://URLs zu registrieren : Universal Links .

Eine sehr grobe Erklärung, wie es funktioniert:

  • Sie erklären Interesse daran, http://URLs für bestimmte Domains (Web-URLs) in Ihrer App zu öffnen.
  • Auf dem Server der angegebenen Domänen müssen Sie angeben, welche URLs in welcher App geöffnet werden sollen, die Interesse am Öffnen von URLs aus der Serverdomäne bekundet hat.
  • Der iOS-URL-Ladedienst überprüft alle Versuche, http://URLs für ein Setup zu öffnen, wie oben erläutert, und öffnet die richtige App automatisch, wenn sie installiert ist. ohne vorher Safari zu durchlaufen ...

Dies ist der sauberste Weg, um Deep Links unter iOS zu erstellen. Leider funktioniert dies nur unter iOS9 und neueren Versionen.

Severin
quelle
und es funktioniert nicht innerhalb des Browsers ... nur außerhalb, wie von Nachrichten oder Notizen
Mihey Mik
9

Nochmals auf die Antwort von Nathan und JB bauen:

So starten Sie die App über eine URL ohne zusätzlichen Klick Wenn Sie eine Lösung bevorzugen, die den Zwischenschritt des Klickens auf einen Link nicht enthält, können Sie Folgendes verwenden. Mit diesem Javascript konnte ich ein Httpresponse-Objekt von Django / Python zurückgeben, das eine App erfolgreich startet, wenn sie installiert ist, oder alternativ den App Store im Falle einer Zeitüberschreitung startet. Hinweis: Ich musste auch die Zeitüberschreitung von 500 auf 100 anpassen, damit dies auf einem iPhone 4S funktioniert. Testen und optimieren Sie, um es für Ihre Situation richtig zu machen.

<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>
BFar
quelle
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 Um festzustellen, ob Ihre App bereits aufgerufen wurde und die aktuelle Registerkarte "Safari" in den Hintergrund tritt, stammt dieser Code von www.baidu.com

Zyanlu
quelle
Ich habe diese Lösung getestet und festgestellt, dass das Fehlerdialogfeld "Safari kann diese Seite nicht öffnen, da die Adresse ungültig ist" vorübergehend angezeigt wird, obwohl Ereignisse ordnungsgemäß übertragen werden. (Es wird nach einem Bruchteil einer Sekunde automatisch geschlossen.)
Michaelhanson
Verwenden Sie einen Iframe zum Laden appurlund weburlkönnte Ihr Problem lösen
Zyanlu
1
@zyanlu: Ich habe es mit iFrame versucht. bt immer noch Safari zeigt den gleichen Fehler.
Kunjus
5

Wenn Sie iframeauf Ihrer Webseite ein srcbenutzerdefiniertes Schema für Ihre App hinzufügen , leitet iOS automatisch zu diesem Speicherort in der App weiter. Wenn die App nicht installiert ist, passiert nichts. Auf diese Weise können Sie eine Deep Link-Verbindung zur App herstellen, wenn diese installiert ist, oder zum App Store umleiten, wenn sie nicht installiert ist.

Wenn Sie beispielsweise die Twitter-App installiert haben und zu einer Webseite mit dem folgenden Markup navigieren, werden Sie sofort zur App weitergeleitet.

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

Hier ist ein ausführlicheres Beispiel, das zum App Store weiterleitet, wenn die App nicht installiert ist:

<!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>
q0rban
quelle
Das Problem bei Ihrem ersten Beispiel ist, dass bei einer Rückkehr zu Mobile Safari "Die Twitter-App ist nicht installiert" angezeigt wird, obwohl Twitter gestartet wurde. Gleiches gilt für das zweite Beispiel, in dem "Website-Inhalt" angezeigt wird. Wenn die App installiert ist, muss Code vorhanden sein, der etwas anderes bewirkt (eine andere URL lädt oder eine von zwei Nachrichten anzeigt).
Mahboudz
1
Ja, @mahboudz, wenn Sie den Text lesen, ist dies nur ein einfaches Beispiel, um zu zeigen, dass es möglich ist, automatisch zur App umzuleiten.
Q0rban
Ich folge dann einem gründlicheren Beispiel, das den tatsächlichen Inhalt der Website zeigt. Ich kann den Text "Die Twitter-App ist nicht installiert" löschen, wenn dies klarer wird.
Q0rban
ios 6 zeigt immer noch Popup Diese Seite kann wegen der ungültigen URL nicht geöffnet werden
Andrei Shender
@AndreiShender, hier sind iOS-Nutzungsstatistiken zum Zeitpunkt des Schreibens: monosnap.com/image/8eXUcpEUi8fm94DiMZIdiIp4xUNaln.png iOS 8: 72%, iOS 7: 25%, frühere Versionen: 3%
q0rban
4

Hier ist eine Lösung.

Richten Sie eine boolesche Situation mit Unschärfe und Fokus ein

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

Binden Sie Ihren Link mit einem JQuery-Click-Handler, der so etwas aufruft.

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

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

Wenn die App geöffnet wird, verlieren wir den Fokus auf das Fenster und der Timer endet. Ansonsten bekommen wir nichts und laden die übliche Facebook-URL.

Däne Macaulay
quelle
Vielen Dank für den Vorschlag. Ich stehe vor dem Problem, dass der Dialog "Externe Anwendung starten" ausreicht, damit die Unschärfe die Flagge inaktiviert. Dies geschieht auch dann, wenn die App nicht installiert ist (z. B. wenn Sie auf einen Link klicken, um eine iPhone-App auf einem Desktop zu starten). Ideen?
Fluxon
2

Soweit ich weiß, können Sie nicht das gesamte Betriebssystem dazu bringen, eine http:+ Domain-URL zu verstehen . Sie können nur neue Schemata registrieren (ich verwende sie x-darkslide:in meiner App). Wenn die App installiert ist, startet Mobile Safari die App korrekt.

Sie müssten jedoch den Fall behandeln, in dem die App nicht mit einem "Immer noch hier? Klicken Sie auf diesen Link, um die App von iTunes herunterzuladen" installiert wird. auf Ihrer Webseite.

Fraser Speirs
quelle
2
Dies ist nicht mehr korrekt: Mit iOS9 und neueren Android-Versionen können Sie Ihre App registrieren, um auf bestimmte httpURLs zu
warten
0

Überprüfen Sie den User-Agent und öffnen Sie für den Fall, dass es sich um Mobile Safari handelt, eine myprotocol: // URL, um die iPhone-App zu öffnen (versuchen) und Mobile iTunes zum Herunterladen der App zu öffnen, falls der Versuch fehlschlägt

Das klingt für mich nach einem vernünftigen Ansatz, aber ich glaube nicht, dass Sie es schaffen werden, mobile iTunes als zweiten Ausweg zu öffnen. Ich denke, Sie müssen das eine oder das andere auswählen - entweder zu Ihrer App oder zu iTunes umleiten.

Wenn Sie also zu myprotocol: // umleiten und die App nicht auf dem Telefon ist, erhalten Sie keine zweite Chance, zu iTunes umzuleiten.

Sie könnten vielleicht zuerst zu einer (für das iPhone optimierten) Zielseite umleiten und dem Benutzer die Möglichkeit geben, sich zu Ihrer App oder zu iTunes durchzuklicken, um die App zu erhalten, wenn er sie nicht hat? Sie verlassen sich jedoch darauf, dass der Benutzer dort das Richtige tut. (Bearbeiten: obwohl Sie ein Cookie so setzen könnten, dass es nur zum ersten Mal ist?)

frankodwyer
quelle
1
Das ist falsch. Wenn ein Fehler angezeigt wird, dass die Seite nicht geöffnet werden kann (App nicht installiert), wird JS weiterhin ausgeführt. Deshalb können Sie dann zu einer anderen Fallback-Lösung umleiten.
Erik
0

Bei dem Versuch, das Problem des Popups zu beheben, stellte ich fest, dass Apple dieses Problem umgehen konnte.

Wenn Sie auf diesen Link klicken und die Anwendung installiert haben, wird sie tatsächlich umgeleitet. Andernfalls werden Sie ohne Popup auf die Webseite weitergeleitet.

Titignes
quelle
3
Ich habe mich ziemlich eingehend mit der Funktionsweise dieses Links befasst, und das Beste, was ich finden kann, ist, dass es sich überhaupt nicht um eine JavaScript-Lösung handelt. Apple scheint einen speziellen URL-Handler für seine App registriert zu haben, für den kein benutzerdefiniertes Protokoll erforderlich ist und der stattdessen mit einer URL-Zeichenfolge übereinstimmt. Der Link, den Sie senden, leitet sofort mit einem 303 hierher weiter . Wenn Sie diesen Link in einer E-Mail an sich selbst senden, können Sie feststellen, dass durch Klicken darauf die AppStore-App direkt aufgerufen wird, wenn sie installiert ist
Casey
Sehr interessant. Sie haben Recht: Wenn ich darauf klicke, wird die AppStore-App angezeigt, sofern sie installiert ist. Wenn Sie jedoch einige Parameter bis "Feiertage" löschen, wird dies in Safari angezeigt. Apple kann ein spezielles URL-Schema registrieren ...
Titignes
@Titignes, könnten Sie bitte auf diese Weise näher erläutern, um eine App oder eine Webseite zu öffnen. Was ist das Muster für die Erstellung einer solchen URL?
Andrei Shender