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

223

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

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

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

Одна идея:

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

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

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

Мартейн Тэ
источник
4
В метро Нью-Йорка есть Wi-Fi от Boingo, который предоставляет вам бесплатный доступ к WiFi, если вы загружаете приложение, которое они рекомендуют. Как только вы загрузите его, вы вернетесь в Safari, и браузер обнаружит его установку, а затем предоставит вам доступ. Есть идеи, как это делается?
TommyG
2
Universal Links теперь будет поддерживать этот вариант использования без каких-либо сообщений об ошибках. Вот как настроить ваш домен и приложение: blog.branch.io/…
Алекс Остин

Ответы:

243

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

  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 и закрывает модальное

Другой вариант, с которым я поиграл, но нашел немного неуклюжим, заключался в том, чтобы сделать следующее в 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
Отличное решение. Если ваш запасной вариант относится к другому приложению, оно будет загружено НЕМЕДЛЕННО без отображения ошибки. Поэтому вместо того, чтобы возвращаться на itunes.com ... используйте itms: //phobos.apple.com / ..., чтобы избежать ошибки всплывающего окна!
JB.
47
Проблема : при window.location="custom-uri://успешном завершении резервный таймаут не уничтожается. Когда пользователь возвращается в браузер из вашего приложения, таймер все еще там и запустит ссылку на магазин приложений. Это плохой пользовательский опыт.
JoJo
5
Кажется, файлы cookie находятся в изолированной среде # ios6, поэтому вы не можете получить доступ к файлам cookie, установленным приложением, из другого. (Приложение WebUI и Safari Mobile, например)
Оливье Эмблет
2
Кто-нибудь находит способ предотвратить срабатывание исходного тайм-аута, когда пользователь возвращается в браузер? (upvoted проблема JoJo упоминает)
cobolstinks
2
Чтобы решить проблему, о которой упоминает JoJo, запускайте код только в том случае, если не прошло «много времени» с тех пор, как пользователь щелкнул ссылку. Посмотрите это решение: stackoverflow.com/a/14751543/533420
kkara
95

Это вполне возможно сделать в 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>

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

ДБ.
источник
7
Согласитесь с Ли, это кажется более простым решением - хотя я все равно получаю сообщение об ошибке от safari, если приложение не существует и оно перенаправляет в магазин приложений.
Джон
2
Я использовал это решение для Android и iOS. Я обнаружил, что при изменении значения времени ожидания с 500 на 100 у меня не появляется всплывающее диалоговое окно «Не удается открыть страницу» в iOS. Я также обнаружил, что тайм-аут должен быть 50 для Android
Россини
14
Использование «itms-apps:» вместо «itms:» сохраняет 1 перенаправление и непосредственно открывает страницу приложения в магазине приложений.
Немецкий Latorre
9
Кто-нибудь знает, как избежать сообщения об ошибке «Не удается открыть страницу» от Safari, если приложение не установлено и перед перенаправлением в магазин приложений?
Давидк
26

Для устройств iOS 6 есть опция: Продвижение приложений с помощью смарт-баннеров приложений.

ohho
источник
12
К сожалению, Smart App Banner поддерживается только в Mobile Safari, но не в UIWebviewComponent. Так что не будет отображаться, если ваш сайт отображается в клиенте Twitter для примера.
Оливье Эмблет
24

Я обнаружил, что выбранный ответ работает для приложений браузера, но у меня были проблемы с кодом, работающим в не браузерных приложениях, которые реализуют 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должно работать нормально.

cnotethegr8
источник
1
Оно работает!! Спасибо, я наконец нашел решение, которое работает на любом браузере.
Колерор
2
Это лучшее решение, если оно найдено. Спасибо. Больше нет ошибки всплывающего окна.
конфил
1
@Tim, если вы хотите, чтобы этот код срабатывал при щелчке по ссылке, затем оберните этот код в функцию, которая вызывается после щелчка по ссылке.
cnotethegr8
1
@ cnotethegr8 Я поместил его в функцию и перенаправил на пользовательский URL-адрес, он отлично работает, но откат к iTunes - нет. Вот мой код . Чего мне не хватает?
Тим
1
Кто-нибудь еще имел проблемы с этим в iOS 9. Это больше не работает для меня в Safari.
Bgolson
20

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

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

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

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

Северин
источник
и он не работает внутри браузера ... только снаружи, как из imessage или заметок
Михей Мик
9

СТРОИТЕЛЬСТВО снова на ответе Натана и 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>
BFar
источник
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 чтобы определить, запущено ли уже ваше приложение, а текущая вкладка сафари переходит в фоновый режим, этот код взят с www.baidu.com

zyanlu
источник
Я проверил это решение и обнаружил, что, хотя оно доставляет события правильно, «Safari не может открыть эту страницу, потому что адрес неверен», на мгновение появляется диалоговое окно с ошибкой. (Это автоматически отклоняет после доли секунды).
Майклхансон
используйте iframe для загрузки appurlи weburlможете решить вашу проблему
zyanlu
1
@zyanlu: я пытался с iFrame. Bt все еще Safari показывает ту же ошибку.
kunjus
5

Если вы добавите 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>
q0rban
источник
Проблема с вашим первым примером заключается в том, что если вы вернетесь в Mobile Safari, на нем будет отображаться «Приложение Twitter не установлено», даже если Twitter был запущен. То же самое со вторым примером, отображающим «контент сайта». Должен быть код, который делает что-то другое (загружает другой URL или отображает одно из двух сообщений), если приложение установлено.
Махбудз
1
Да, @mahboudz, если вы читаете текст, это просто простой пример, демонстрирующий возможность автоматического перенаправления в приложение.
q0rban
Затем я приведу более подробный пример, который покажет фактическое содержание сайта. Я могу удалить текст «Приложение Twitter не установлено», если это сделает его более понятным.
q0rban
На ios 6 все еще отображается всплывающее окно. Невозможно открыть эту страницу из-за неверного URL
Андрей Шендер,
@AndreiShender, вот статистика использования iOS на момент написания этой статьи: monosnap.com/image/8eXUcpEUi8fm94DiMZIdiIp4xUNaln.png iOS 8: 72%, iOS 7: 25%, более ранние версии: 3%
q0rban
4

Вот решение.

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

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

Датчанин маколей
источник
Большое спасибо за предложение. Я сталкиваюсь с проблемой, что диалоговое окно «Запустить внешнее приложение» кажется достаточным для размытия, чтобы деактивировать флаг. Это происходит, даже если приложение не установлено (например, при нажатии на ссылку, предназначенную для запуска приложения iPhone на рабочем столе). Идеи?
Fluxon
2

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

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

Фрейзер Спирс
источник
2
Это больше не правильно: с iOS9 и последними версиями Android вы можете зарегистрировать свое приложение для прослушивания определенных httpURL
severin
0

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

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

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

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

frankodwyer
источник
1
Это неверно. Если отображается ошибка, что страница не может быть открыта (приложение не установлено), JS все еще выполняется. Вот почему вы можете перенаправить на другое резервное решение.
Эрик
0

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

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

Titignes
источник
3
Я довольно глубоко вник в то, как работает эта ссылка, и лучшее, что я могу придумать, это то, что это вообще не решение JavaScript. Apple, кажется, зарегистрировала специальный обработчик URL для своего приложения, который не требует специального протокола и вместо этого сопоставляет некоторые строки URL. Ссылка, которую вы отправляете, перенаправляет сразу с 303 здесь . Если вы отправите эту ссылку в электронном письме себе, вы можете заметить, что нажатие на нее приведет к прямому вызову приложения AppStore, если оно установлено
Кейси
Очень интересно. Вы правы: если я нажму на него, то откроется приложение AppStore, если оно установлено. Но если вы удаляете некоторые параметры до «праздников», они появляются в Safari. Apple может зарегистрировать специальную схему URL-адресов ...
Titignes
@Titignes, не могли бы вы уточнить, как открыть приложение или веб-страницу. Каков шаблон для создания такого URL?
Андрей Шендер