Можно ли зарегистрировать схему URL-адресов на базе домена http+ для приложений iPhone, таких как YouTube и Карты?

Я хотел бы, чтобы iOS открывала URL-адреса из моего домена (например, http://martijnthe.nl/) с моим приложением всякий раз, когда приложение установлено на телефоне, и с Mobile Safari, если это не так.

Я читал, что для этого можно создать уникальный суффикс протокола и зарегистрировать его в Info.plist, но Mobile Safari выдаст ошибку, если приложение не установлено.

Что бы обойти?

Одна идея:

1) Используйте http:// URL, которые открываются в любом настольном браузере и предоставляют сервис через браузер

2) Проверьте User-Agent и, если это Mobile Safari, откройте myprotocol:// URL, чтобы (попытаться) открыть приложение iPhone и откройте Mobile iTunes для загрузки приложения в случае неудачной попытки.

Не уверен, что это сработает... предложения? Спасибо!

12 ответов

Решение

Я думаю, что наименее навязчивый способ сделать это заключается в следующем:

  1. Проверьте, является ли пользовательский агент iPhone / iPod Touch
  2. Проверьте на appInstalled печенье
  3. Если файл cookie существует и имеет значение true, установите window.location в your-uri:// (или перенаправить серверную часть)
  4. Если cookie не существует, откройте "Знаете ли вы, что у вашего сайта есть приложение для iPhone?" модальный с "Да, у меня уже есть", "Нет, но я бы хотел попробовать" и "Оставь меня в покое".
    1. Кнопка "Да" устанавливает cookie на true и перенаправляет на your-uri://
    2. Кнопка "Нет" перенаправляет на " http://itunes.com/apps/yourappname", который открывает App Store на устройстве.
    3. Кнопка "Оставь меня в покое" устанавливает cookie в false и закрывает модальное

Другой вариант, с которым я поиграл, но нашел немного неуклюжим, заключался в следующем:

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://";

Это вполне возможно сделать в JavaScript, если ваш запасной вариант - еще одна ссылка на приложение. Опираясь на предложение Натана:

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

Проверьте живую демонстрацию здесь.

Я обнаружил, что выбранный ответ работает для приложений браузера, но у меня были проблемы с кодом, работающим в не браузерных приложениях, которые реализуют UIWebView,

Проблема для меня заключалась в том, что пользователь в приложении Twitter нажимал на ссылку, по которой он переходил на мой сайт через UIWebView в приложении Twitter. Затем, когда они нажали кнопку на моем сайте, Твиттер пытается проявить фантазию и завершить только window.location если сайт доступен. Так что же происходит UIAlertView всплывающее окно с сообщением вы уверены, что хотите продолжить, а затем сразу же перенаправляет в App Store без второго всплывающего окна.

Мое решение включает в себя iframes. Это позволяет избежать UIAlertView быть представленным для простого и элегантного пользовательского опыта.

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

РЕДАКТИРОВАТЬ:

Добавьте абсолютную позицию в iframe, чтобы при вставке не было случайных битов в нижней части страницы.

Также важно отметить, что я не нашел необходимости в этом подходе с Android. С помощью window.location.href должно работать нормально.

В iOS9 Apple наконец-то представила возможность зарегистрировать ваше приложение для обработки определенных http:// URL-адреса: универсальные ссылки.

Очень грубое объяснение того, как это работает:

  • Вы заявляете о заинтересованности в открытии http:// URL-адреса для определенных доменов (веб-URL) в вашем приложении.
  • На сервере указанных доменов необходимо указать, какие URL открывать в каком приложении, которое заявило о своей заинтересованности в открытии URL из домена сервера.
  • Служба загрузки URL iOS проверяет все попытки открыть http:// URL для настройки, как описано выше, и автоматически открывает правильное приложение, если оно установлено; не пройдя сафари сначала...

Это самый чистый способ делать глубокие ссылки на iOS, к сожалению, он работает только в iOS9 и новее...

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

document.webkitHidden чтобы определить, запущено ли уже ваше приложение, а текущая вкладка сафари переходит в фоновый режим, этот код взят с www.baidu.com

СТРОИТЕЛЬСТВО снова на ответе Натана и JB:

Как запустить приложение из URL без дополнительного клика Если вы предпочитаете решение, которое не включает промежуточный шаг щелчка по ссылке, можно использовать следующее. С помощью этого javascript я смог вернуть объект Httpresponse из Django/Python, который успешно запускает приложение, если оно установлено, или, альтернативно, запускает магазин приложений в случае тайм-аута. Обратите внимание, мне также нужно было настроить период ожидания от 500 до 100, чтобы это работало на iPhone 4S. Протестируйте и настройте его, чтобы он подходил для вашей ситуации.

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

Если вы добавите iframe на вашей веб-странице с src Если для вашего приложения выбрана индивидуальная схема, iOS автоматически перенаправит на это место в приложении. Если приложение не установлено, ничего не произойдет. Это позволяет вам делать глубокие ссылки на приложение, если оно установлено, или перенаправлять в App Store, если оно не установлено.

Например, если у вас установлено приложение twitter и вы перейдете на веб-страницу, содержащую следующую разметку, вы сразу будете перенаправлены в приложение.

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

Вот более подробный пример, который перенаправляет в магазин приложений, если приложение не установлено:

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

Вот решение.

Настройте логическое положение, используя размытие и фокус

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

Свяжите свою ссылку с обработчиком щелчков jquery, который вызывает что-то вроде этого.

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

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

если приложение откроется, мы потеряем фокус на окне и таймер закончится. в противном случае мы ничего не получаем и загружаем обычный URL-адрес Facebook.

Вы не можете, насколько я знаю, заставить всю ОС понимать http:+ URL домена. Вы можете только зарегистрировать новые схемы (я использую x-darkslide: в моем приложении). Если приложение установлено, Mobile Safari правильно его запустит.

Однако вам придется обработать случай, когда приложение не установлено, с надписью "Все еще здесь? Нажмите эту ссылку, чтобы загрузить приложение из iTunes". на вашей веб-странице.

Также можно проверить активность вкладки, document.hidden свойство

Возможное решение

document.location = 'app://deep-link';

setInterval( function(){
  if (!document.hidden) {
    document.location = 'https://app.store.link';
  }
}, 1000);

Но похоже, что это не работает в Safari

Пытаясь решить проблему всплывающих окон, я обнаружил, что у Apple есть способ обойти эту проблему.

Действительно, когда вы нажимаете на эту ссылку, если вы установили приложение, оно перенаправляется на него; в противном случае вы будете перенаправлены на веб-страницу без всплывающего окна.

Проверьте User-Agent и, если это Mobile Safari, откройте myprotocol:// URL, чтобы (попытаться) открыть приложение iPhone, и откройте Mobile iTunes для загрузки приложения в случае неудачной попытки.

Это звучит разумно для меня, но я не думаю, что вы сможете заставить его открывать мобильные itunes в качестве второго средства. Я думаю, вам придется выбрать один или другой - либо перенаправить на ваше приложение или Itunes.

то есть, если вы перенаправляете на myprotocol://, а приложение отсутствует на телефоне, у вас не будет второго шанса перенаправить на itunes.

Возможно, вы могли бы сначала перенаправить на целевую страницу (оптимизированную для iphone) и дать пользователю возможность перейти к вашему приложению или к itunes, чтобы получить приложение, если у него его нет? Но вы будете полагаться на то, что пользователь поступит правильно. (Изменить: хотя вы могли бы установить cookie, чтобы это было только в первый раз?)

Другие вопросы по тегам