Чи можна зареєструвати схему URL-адрес на основі домену + для таких додатків iPhone, як YouTube та Карти?


223

Мені б хотілося, щоб iOS відкривав URL-адреси з мого домену (наприклад, http://martijnthe.nl ) за допомогою мого додатка щоразу, коли додаток встановлено на телефон, і мобільний Safari у випадку, якщо його немає.

Я прочитав, що можна створити для цього унікальний суфікс протоколу і зареєструвати його в Info.plist, але Mobile Safari видасть помилку, якщо додаток не встановлено.

Що б було вирішити?

Одна ідея:

1) Використовуйте http: // URL-адреси, які відкриваються в будь-якому браузері настільних ПК та надають послугу через браузер

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

Не впевнені, чи спрацює це ... пропозиції? Дякую!


4
У метро NYC є wifi від Boingo, який надає вам безкоштовний доступ до WiFi, якщо ви завантажите програму, яку вони рекомендують. Завантаживши його, ви повернетесь до Safari і браузер виявить, чи він був встановлений, і надасть вам доступ. Будь-яка ідея, як це робиться?
TommyG

2
Універсальні посилання тепер підтримують цей випадок використання без жодного повідомлення про помилку. Ось як налаштувати свій домен і додаток: blog.branch.io/…
Алекс Остін

Відповіді:


243

Я думаю, що найменш нав'язливий спосіб зробити це:

  1. Перевірте, чи є користувальницький агент у iPhone / iPod Touch
  2. Перевірте appInstalledпечиво
  3. Якщо печиво існує і має значення для справжнього, набору window.locationдля your-uri://(або зробити на стороні сервера перенаправлення)
  4. Якщо файл cookie не існує, відкрийте "Чи знаєте ви, що у вашому імені веб-сайту є програма для iPhone?" модальний за допомогою кнопок "Так, у мене вже є", "Ні, але я б хотів спробувати" та "Залиште мене в спокої".
    1. Кнопка "Yep" встановлює файл cookie істинним та переспрямовує на your-uri://
    2. Кнопка "Nope" переспрямовує на " http://itunes.com/apps/yourappname ", яка відкриє App Store на пристрої
    3. Кнопка «Залиште мене в спокої» встановлює файл cookie на помилковий і закриває модальний

Інший варіант, з яким я грав, але виявив трохи незграбності, це зробити наступне в 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
Хтось знайде спосіб запобігти появі оригінального тайм-ауту, коли користувач повернеться до браузера? (згадується проблема 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
Погодьтеся з Лі, це здається більш простим рішенням - хоча я все-таки отримую повідомлення про помилку від сафарі, якщо додаток не існує, і він перенаправляє в магазин додатків.
Джон

2
Я використовував це рішення і для Android, і для iOS. Я виявив, що якщо я зміню значення тайм-ауту з 500 на 100, я не отримую спливаюче діалогове вікно "Не вдається відкрити сторінку" в iOS. Також я виявив, що час очікування повинен бути 50 для Android
Россіні

14
Використовуючи "itms-apps:" замість "itms:" зберігає 1 переадресацію та безпосередньо відкриває сторінку програми в appstore.
Німецький Латоре


9
Хтось знає, як уникнути повідомлення про помилку "не вдається відкрити сторінку" від сафарі, якщо додаток не встановлено та перед перенаправленням у магазин додатків?
davidk

26

12
На жаль, смарт-банер додатків підтримується лише в мобільному Safari, а не в UIWebviewComponent. Тож не буде відображатися, якщо ваш сайт відображається у клієнті Twitter для прикладу.
Олів'є Амблет

24

Я виявив, що вибрана відповідь працює для програм браузера, але у мене виникли проблеми з кодом, що працює в додатках, які не використовують браузер, які реалізують a UIWebView.

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

Моє рішення передбачає рамки кадрів. Це дозволяє уникнути 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://');

Редагувати:

Додайте абсолютну позицію до рамки кадрів, тому при вставці не буде випадкового бітового простору внизу сторінки.

Також важливо зазначити, що я не знайшов потреби в такому підході з Android. Використання window.location.hrefмає справно працювати.


1
Це працює!! Дякую, я нарешті знайшов рішення, яке працює у кожному браузері.
колерор

2
Це найкраще рішення, якщо його знайдуть. Дякую. Більше не з’являється спливаючих помилок.
confile

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-адреси для налаштування, як пояснено вище, і автоматично відкриє правильний додаток, якщо встановлено; не переходячи через Safari спочатку ...

Це найчистіший спосіб глибокого зв’язку на iOS, на жаль, він працює лише в iOS9 та новіших версіях ...


і він не працює всередині веб-переглядача ... лише зовні, як, наприклад, від хвороби чи заміток
Mihey Mik

9

БУДІВЛЕННЯ знову на відповідь Натана та Дж.

Як запустити додаток із 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>

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


Я перевірив це рішення і виявив, що, хоча воно належним чином доставляє події, на мить з'являється діалогове вікно помилок "Safari не може відкрити цю сторінку, оскільки адреса недійсна". (Він автоматично відміняється через частку секунди).
michaelhanson

використовуйте iframe для завантаження appurlта weburlзможете вирішити вашу проблему
zyanlu

1
@zyanlu: я спробував з iFrame. bt досі safari показує ту ж помилку.
кунджус

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>

Проблема з вашим першим прикладом полягає в тому, що якщо ви повернетесь до мобільного Safari, він відобразить "Додаток Twitter не встановлено", навіть незважаючи на те, що Twitter був запущений. Те саме з другим прикладом, що відображає "Вміст веб-сайту". Потрібно ввести код, який робить щось інше (завантажує іншу URL-адресу або відображає одне з двох повідомлень), якщо додаток встановлено.
mahboudz

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

якщо програма відкриється, ми втрачаємо увагу на вікні і таймер закінчується. інакше ми нічого не отримуємо, і завантажуємо звичайну адресу facebook.


Дякую за пропозицію. Я зіткнувся з проблемою, що діалог "запуск зовнішньої програми" здається достатнім для розмиття, щоб інактивувати прапор. Це трапляється навіть у тому випадку, якщо додаток не встановлено (наприклад, при натисканні на посилання для запуску програми iPhone на робочому столі). Ідеї?
флюксон

2

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

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


2
Це вже не правильно: за допомогою iOS9 та останніх версій Android ви можете зареєструвати додаток, щоб слухати певні httpURL-адреси
severin

0

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

Це звучить для мене розумним підходом, але я не думаю, що вам вдасться змусити його відкривати мобільні програми в якості другого засобу. Я думаю, що вам доведеться вибрати те чи інше - або переадресувати на ваш додаток, або на itunes.

тобто, якщо ви переспрямовуєте на myprotocol: //, і додаток не знаходиться на телефоні, ви не отримаєте другого шансу перенаправити на ітони.

Можливо, ви можете спочатку переспрямувати на (оптимізовану для iphone) цільову сторінку і дати користувачеві можливість перейти до вашого додатка або до програми, щоб отримати додаток, якщо у нього немає? Але ви будете покладатися на користувача, щоб зробити там все правильно. (Редагувати: хоча ви можете встановити файл cookie так, що це лише перший раз?)


1
Це неправильно. Якщо відображається помилка, що сторінку неможливо відкрити (додаток не встановлено), JS все одно виконується. Ось чому ви можете перенаправити на інше резервне рішення.
Ерік

0

Прагнучи виправити проблему спливаючих вікон, я виявив, що Apple вирішила цю проблему.

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


3
Я досить глибоко занурився в те, як працює це посилання, і найкраще, що я можу придумати, - це те, що це зовсім не рішення JavaScript. Apple, схоже, зареєструвала спеціальний обробник URL-адрес для свого додатка, який не потребує користувальницького протоколу, а натомість є деяким збігом у рядку URL. Посилання ви відправляєте переадресовує відразу з 303 до сюди . Якщо ви надішлете це посилання електронною поштою, ви можете помітити, що натискання на нього безпосередньо приведе додаток AppStore, якщо він встановлений
Casey

Дуже цікаво. Ви маєте рацію: якщо я натискаю на нього, він відкриває додаток AppStore, якщо він встановлений. Але якщо ви видалите деякі параметри до "свят", це відображається в Safari. Apple може зареєструвати спеціальну схему URL-адрес ...
Titignes

@Titignes, чи можете ви детальніше розробити цей спосіб, щоб відкрити додаток чи веб-сторінку. Яка схема побудови такої URL-адреси?
Андрій Шендер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.