Браузер iPhone: проверка, установлено ли приложение iPhone из браузера

У меня есть веб-страница, где у меня есть кнопка, которая либо открывает приложение (если оно установлено), либо направляет в магазин приложений, если приложение не установлено. Все работает, если приложение установлено (я звоню в "MYAPP://"). Однако, если приложение не установлено, Safari показывает сообщение об ошибке "Невозможно открыть URL" и все. Есть ли способ отключить это сообщение из JScript или есть другой способ узнать из JScript, если приложение установлено (вместо того, чтобы нажать на URL приложения)?

Модератору: я видел, как кто-то задал похожий вопрос, и модератор ошибочно пометил его как дубликат. Пожалуйста, поймите, что этот вопрос был конкретно о том, как сделать это из браузера

Нашел несколько подходящее решение здесь

Кстати, если кто-то интересуется, как сделать то же самое для Android, вот код. Мы используем библиотеку 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";
    }
  });

5 ответов

В Branch мы используем форму кода ниже - обратите внимание, что iframe работает в большем количестве браузеров. Просто замените его в URI вашего приложения и на ссылку в App Store. Кстати, использование iframe заставляет замолчать ошибку, если у них не установлено приложение. Это великолепно!

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

Если у других есть лучшие решения, чтобы определить, действительно ли вызов схемы URI действительно не удался, пожалуйста, напишите! Я не видел ни одного, и я потратил кучу времени на поиски. Все существующие решения зависят только от пользователя, который все еще находится на странице, и от запуска setTimeout.

Вот код, который работает на iOs, даже если все еще отображается "Не удается открыть URL".

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

Спасибо за решение для Android.

Я объединил несколько вещей и использовал следующий код, чтобы проверить, является ли это устройством iOS, прежде чем использовать метод try / catch из chazbot. К сожалению, устройство все еще выдает всплывающее окно пользователю, говорящему, что адрес недействителен... кто-нибудь знает, является ли это ожидаемым поведением при попытке открыть недопустимый URL в блоке 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
    }

Есть несколько вещей, которые вы можете сделать, чтобы улучшить другие ответы. Начиная с iOS 9, ссылку можно открыть в UIWebView или в SFSafariViewController, Вы могли бы хотеть обращаться с ними по-другому.

SFSafariViewController делится файлами cookie между приложениями и со встроенным Safari. Таким образом, в вашем приложении вы можете сделать запрос через SFSafariViewController при этом будет установлен файл cookie с надписью "мое приложение установлено". Например, вы открываете свой веб-сайт, запрашивая у вашего сервера такой файл cookie. Тогда в любое время вы получите запрос от SFSafariViewController Вы можете проверить этот файл cookie и перенаправить на MYAPP:// если вы найдете его, или в магазине приложений, если вы этого не сделаете. Нет необходимости открывать веб-страницу и выполнять перенаправление JavaScript, вы можете сделать 301 с вашего сервера. Приложения, такие как Messages или же Safari поделитесь этими куки.

UIWebView очень хитрый, так как он полностью изолирован и изолирован от других файлов cookie. Поэтому вам придется вернуться к тому, что было описано в других ответах:

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);  
};

Я нахожу это раздражающим, что это подскажет пользователю, если они хотят покинуть текущее приложение (чтобы перейти к вашему приложению), даже если ваше приложение не установлено. (эмпирически, что кажется верным только из UIWebView, если вы делаете это из обычного Safari, например, что не произойдет), но это все, что мы получили!

Вы можете дифференцировать UIWebView от SFSafariViewController с вашего сервера, так как они имеют другой заголовок агента пользователя: SFSafariViewController содержит сафари в то время как UIWebView не делает. Например:

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

Другие соображения:

  • При первом подходе вы можете обрабатывать удаление: если пользователь удаляет ваше приложение, у вас все еще есть файл cookie, который сообщает, что приложение есть, но его нет, поэтому вы можете получить "Can not open URL" сообщение. Я обработал его, удалив файл cookie после нескольких попыток, которые не привели к открытию приложения (что я знаю, потому что при каждом открытии приложения я сбрасываю этот файл cookie с ошибками)
  • Во втором случае неясно, лучше ли вам использовать setInterval или же setTimeout, Проблема с тайм-аутом заключается в том, что если он срабатывает при включенном запросе, он будет игнорироваться. Например, если вы откроете ссылку из Messenger, ОС спросит вас "Выйти из Messenger? Вы собираетесь открыть другое приложение", когда iframe попытается загрузить ваше приложение. Если вы не ответите в любом случае в течение 500 мс времени ожидания, перенаправление в тайм-ауте будет игнорироваться.
  • Наконец, хотя UIWebView находится в изолированной программной среде, вы можете дать ему файл cookie, чтобы идентифицировать его, передать его в свою ссылку и сохранить этот идентификатор как соответствующий устройству с вашим приложением на вашем сервере, когда ваше приложение откроется. В следующий раз, если вы увидите такой файл cookie в запросе от UIWebView, вы можете проверить, соответствует ли оно известному устройству с приложением, и перенаправить напрямую с 301, как и раньше.

Я думаю, что вы все еще можете использовать URL-адрес приложения в качестве теста. Попробуйте обернуть его в try...catch блок,

try {
  //run code that normally breaks the script or throws error
}
catch(e) {
  //do nothing
}
Другие вопросы по тегам