Теория Universal Links

image

Введение


WWDC15 – Apple анонсирует переход на Universal Links. Их смысл непомерно прост – отправлять пользователя в приложение, если он переходит на страницу сайта, которую приложение поддерживает. Наиболее часто это применяется в письмах, которые отправляются после регистрации для подтверждения электронной почты. Таким образом, Universal Links избавляет пользователя от необходимости самостоятельно возвращаться в приложение – а это хорошо как для пользовательского опыта, так и для статистики.

image

Многие прямо сейчас могут думать, что эта статья пишется не очень вовремя, однако Вы, дорогой читатель, возможно не видели что происходит на Stackoverflow по теме Universal Links.

Реализация


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

Давай перейдем к первому пункту.

Associated Domains в App IDs


image

Если Вы еще не зарегистрировали App ID для своего приложения, то сделайте это сейчас на сайте Apple Developer. При регистрации убедитесь что подключили Associated Domains. Если же App ID уже зарегистрирован, просто переходите к следующему пункту и включайте Associated Domains напрямую из Xcode.

Associated Domains в Xcode


XcodeProject/Targets/YourApp/Capabilities

Чтобы быть понятным даже новичку, мы не будем делать это напрямую через файл .entitlements и пойдем ясным путем: Xcode → Project → Capabilities → Associated Domains.

Здесь нам нужно нажать на "+" и добавить интересующие нас домены. Домены обязательно добавляются через подпись applink, например…

applink:habr.com

В данном случае мы притворимся, что хотим научить приложение Habr открываться при переходе на один из хабов, поэтому я смело указываю habr.com. На деле у нас не получится протестировать работу Universal Links на Хабре, и если вы сразу решили перейти от теории к практике, то я рекомендую прямо сейчас создать домен на Github Pages и указать его через applink.

AppDelegate.swift


Здесь нам достаточно скопировать и вставить этот код, но далее идет пояснение для пытливых.


func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: [Any?] -> Void) -> Bool {
     guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url =           userActivity.webpageURL else { return false }
     print(url) // В зависимости от URL Вы можете открывать разные экраны приложения.
     return true
}


Когда вы запустите приложение через Universal Link вы получите объект NSUserActivity с значением activityType. Свойство webpageURL содержит URL по которому перешел пользователь, его можно разобрать на части с помощью NSURLComponents.

NSURLComponents – достаточна простая тема которая была множество раз раскрыта небольшими проектами в Playground. Если не понимаете о чем речь, то вот здесь есть хороший скриншот.

Файл apple-app-site-association


Представляет из себя файл без расширения, однако хранит в себе данные в формате JSON. Выглядит он примерно следующим образом.

{
    "applinks": {
        "apps": [],
        "details": [{
            "appID": "teamId.com.bundleId.of.your.app",
            "paths": ["/path-for-redirectionl/*"]
        }]
    }
}

Также, я настоятельно прошу прямо сейчас зафиксировать в памяти, что этот файл должен храниться в корневом каталоге домена.

В коде нас по факту интересуют всего два поля. appID в apple-app-site-association – это комбинация Вашего Team Identifier и Bundle Identifier. В коде выше я уже подставил данные таким образом, чтобы Вам было удобнее скопировать их и изменить пару строк.

Как искать Team Identifier? Для этого перейдем на сайт developer.apple.com → Account → Sign In → Membership. Третье поле – Ваш Team Identifier. Для меня это 74D322Z5HV.

Как искать Bundle Identifier? Xcode → Project → General. Ваш Bundle Identifier написан в секции Identity, второе поле. Для меня это com.habrahabr.ios.application.

Теперь давайте составим из этого appID для apple-app-site-association.

"appID": "74D322Z5HV.com.habrahabr.ios.application"

Готово! Вы восхитительны! Теперь давайте пообщаемся о paths. Это поле прямо в лоб говорит, какие страницы сайта поддерживает приложение, с каких страниц Вас должно отправлять в приложение. Добавить страниц Вы можете сколько угодно. Далее небольшая справка о том, как это работает и чтобы Вам было еще более ясно, я напоминаю, что мы делаем приложение для habr.com

"paths": [
    "/path-for-redirection/*" // Мы перенесемся в приложение при попадании на URL – habr.com/path-for-redirection/ или куда-угодно дальше (за это отвечает *), например при попадании на URL habr.com/path-for-redirection/ok/funny-video-with-dogs/ мы всё равно перейдем в приложение.
    "/path-for-redirection/" // Мы перенесемся в приложение при попадании на URL – habr.com/path-for-redirection/, но мы убрали звездочку, а значит не перенесемся в приложение при попадании на, например, habr.com/path-for-redirection/ok/.
    "*" // Только символ звездочки без указания какого-либо пути значит что мы перенесемся в приложение при попадании вообще на какую угодно страницу сайта.
    "NOT /path-for-redirection/*" // Если выше указана звездочка, а следующей строкой следует какой-угодно URL с приставкой NOT – мы перенесемся в приложение при попадании на любую страницу сайта, кроме той, что указана рядом с NOT.
]

А вот так будет выглядеть apple-app-site-association если у нас, допустим, есть 2 приложения: одно для хаба «Swift», а другое для хаба «Разработка под iOS».

{
    "applinks": {
        "apps": [],
        "details": [{
            "appID": "74D322Z5HV.com.habrahabr.ios.application.iosdev",
            "paths": ["/hub/ios_dev/*"]
            },
            {
            "appID": "74D322Z5HV.com.habrahabr.ios.application.swift",
            "paths": ["/hub/swift/*"]
        }]
    }
}

Теперь Вы можете сохранить файл apple-app-site-association без расширения (формата) и залить его на сервер. Затем отправьте требуемый URL себе на почту, соберите в Xcode проект с Associated Domains и кодом в AppDelegate.swift. Проверять работу следует переходя по нужному URL из стандартного приложения «Почта».

Примечательные факты и советы


  • Universal Links не работает из браузера, при переходе на требуемый URL в Safari Вам покажет плашку, сообщающую что вы можете перейти в приложение.
  • Universal Links не работает в цепочках редиректов (перенаправлений). При попадании на нужный URL сайт просто покажет вверху плашку, сообщающую о том, что вы можете перейти в приложение.
  • Universal Links можно тестировать без собственного выделенного или виртуального сервера с помощью GitHub Pages.
  • URL для перехода обязательно должен начинаться на «https://».
  • Проверять всё ли в порядке с файлом apple-app-site-association можно через App Search API Validation Tool.
  • Чтобы вызвать переход в приложение с нужного URL не обязательно иметь какое-либо наполнение по этому URL. То-есть переход будет осуществлен даже если браузер по этому URL выдаёт 404.
  • Долгое нажатие на Universal Link в приложении почты предложит Вам выбрать между открытием приложения и открытием браузера.

Ссылки и используемая литература


Ввиду того что одна из целей этой публикации – придача максимального понимания Universal Links, я хочу завершить его ссылками на литературу которая использовалась при написании статьи и/или просто даёт более глубокое понимание Universal Links.


Надеюсь, эта публикация стала лучшей, что Вы нашли по теме на русском языке. Кроме этого, я буду рад дополнительно сориентировать вас здесь (в комментариях). Если же я упустил какие-то моменты или в чем-то ошибся, я так-же очень прошу сообщить мне об этом.

Спасибо!
Поделиться публикацией
Комментарии 16
    –4
    Apple продолжает создавать ужасные вещи. Лишает человека выбора и как следствие лишает, адекватного понимания, происходящих процессов. В итоге получаем обезьянок, способных оценивать что-то, только с помощью слов «круто» и «не круто», для которых все происходящее, сплошная магия. Как с такими людьми потом контролировать ИИ, одному AI известно.
      0
      Хотите сказать, что вы идеально понимаете как работают абсолютно все процессы вокруг вас?
      Это мало того, что не особо нужно, так и не особо возможно, в любом случае есть некий уровень абстракции, ниже которого заглядывать не имеет смысла. Исходя из философии эпл, конечная цель у человека, который открывает ссылку — получить контент, а не разбираться что где сработает, как откроет и откроет ли
        0
        Должен быть разумный баланс, понимания и непонимания. Одно дело не понимать как работает та штука, но знать где у нее провод и вилка. Страшнее когда у той штуки батарейка и нет кнопки.
        Уровни абстракций повышаются, желания уходить на низшие уровни все меньше, и это нежелание еще и подогревают. Одно дело когда вы не понимаете что такое USB3.0, это может сподвигнуть разобраться, страшнее когда вы понимаете что это Lightning (молния). У вас неправильная коммутация абстракций.
        Философия эпл проявляется в том, что вы не можете отключить сим-программы, вам их должен отключить оператор. Вы не можете включить режим модема, если оператор против, вы не можете поменять иконку. Вы не можете сохранить HDR, вам отдадут только отредактированный jpeg. Вы нифига не можете пока мы не решим что вы можете и так как мы этого хотим. Вот философия эпл.
          –4
          это лишает человека субъектности и превращает в овощ
            +2
            Но ведь тоже самое можно про все что угодно сказать, где решения приняты за вас, это же абсурдная логика
            В том, что эпл принимает решения за пользователя и есть философия эпл. Пользователи эпл платят как раз за то, что большинство необходимых решений уже сделаны за них, а им останется только пользоваться устройством и решать свои более важные задачи, чем настройка устройства и самовыражение через вариант открытия ссылок
            Также как, например, людям чаще всего все равно через какую из десятков видов труб к ним поступает газ или вода и какой там цемент заливался в их дом, их даже не беспокоит, что их никто об этом не спросил. Главное, что газ/вода есть и стены толстые, не падают. Люди намеренно платят за готовые решения, потому что эти решения их устраивают и сами они не хотят/не могут их принимать, и в этом, как мне кажется, нет абсолютно ничего плохого, потому что современному человеку решений нужно принимать слишком много и детально углубляться в тему для каждого из них просто невозможно
              0
              если человек так занят, зачем ему оставлять клавиатуру с кучей букв, логичнее оставить ему смайлик :)
        +1
        Так в том же андроиде помоему это уже давно работает?
          0
          … и это отвратительно. Бывало, при переходе по ссылке из результатов поиска, вместо Tumblr, я почему-то попадаю в Google Play с предложением установить приложение Tumblr, которое мне нафиг не нужно.
            0

            это абсолютно иное, тут уже сайт сделал переадресацию на маркет.
            тут смысл тот что приложение может обработать ссылку, но оно ДОЛЖНО БЫТЬ установлено.

              0
              ну ВК, инстаграм, медуза — регистрируются в качестве ссылки… И при первом переходе можно выбрать где открывать…
          +1
          В целом сама по себе идея универсальных ссылок неплоха.
          В теории это может разрубить гордиев узел html+javascript, который человечество навязало и уже двацать лет развязать не может.

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

          Будем наблюдать.
            –2
            Да это чудесная технология, которая позволяет взаимодействовать двум процессам (минуя человека) внутри коробки в которую нельзя заглянуть. Прямо мечта мизантропа.
            0
            Задам самый главный вопрос: как совместить Universal Links и другие платформы (Android, Web)? В реальности то хочется иметь ссылку, которая автоматически откроет нужное приложение не только на iOS.
              0
              branch.io например
              0
              Есть еще статья на хабре на эту тему, которая затрагивает достаточно тонкие моменты при реализации
              habr.com/company/jugru/blog/352914
                0
                Спасибо! Всем дочитавшим до этого комментария так-же настоятельно советую к прочтению эту статью.

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

              Самое читаемое