На WWDC 2015 инженеры компании Apple заявили, что пересмотрели подход к Deep Linking, в прошлом году компания Google анонсировала App Index — как новый взгляд на глубинные ссылки, в начале 2015 года в мире мобильной разработки заговорили о контекстных Deep Links. Что это за инструмент и как с ним работать применительно к iOS — расскажу в этой статье.

Что это?


Один из способов увеличения конверсии при продвижении IT-продукта — уменьшение барьеров для достижения пользователями искомой цели. В мобильной разработке эта проблема еще актуальней. При использовании e-mail, push или sms-рассылок с информацией о промо-акциях упрощение доступа к функционалу приложения просто необходимо. В такой ситуации просто запуск приложения из внешнего источника — не решение, ведь промо-акция — это конкретное спец.предложение в конкретном разделе. Чтобы после запуска приложения пользователю не пришлось по нему бродить, искать и раздражаться, нужен дополнительный инструмент, предопределяющий навигацию. И такой инструмент есть.
Deep Linking (глубинное связывание) — технология, благодаря которой пользователь может перемещаться между приложениями в заранее определенные разделы.



Как это работает?


Представим, что пиццерия решила провести рекламную кампанию, в рамках которой предлагает всем желающим купить пиццу «Маргарита» с 50% скидкой. У пиццерии есть веб-сайт и мобильное приложение (последнее, конечно, предпочтительнее для работы с клиентом по маркетинговым соображениям, да и операции с банковской картой в приложении гораздо удобнее, чем в браузере). Компания делает sms-рассылку по своей клиентской базе с информацией о спец.предложении и дает ссылку на нужный раздел сайта. Если на смартфоне клиента установлено приложение пиццерии, то при переходе по ссылке сервер сайта отправит клиента сразу в нужный раздел аппа для оформления заказа (это и есть механизм Deep Linking), если приложения на смартфоне нет, клиенту предложат установить его в сторе и затем повторно перейти по ссылке в sms (или продолжить пользоваться веб-версией).

В концепции всемирного Web механизм Deep Linking был заложен в HTTP и URL, как возможность перемещения между любыми документами в сети, а не только корневыми страницами. В мобильных операционных системах данный механизм реализуется разными способами.

Как это сделать в iOS


Принцип работы Deep Linking заключается в следующем: пользователь инициирует переход по URL, ресурс, находящийся по этой URL, определяет операционную систему и соответствующим образом осуществляет переход в приложение в заранее определенный раздел.

URL — ссылка, указывающая на местонахождение какого-либо ресурса. Используется преимущественно для адресации в сети, но может быть использована для указание местоположения в файловой системе.

У этой технологии есть несколько способов реализации:
  • Классический подход
  • Сторонние решения
  • Новые веянья с IT-полей

Классическая реализация в iOS


Общепринятая реализация состоит из следующих этапов:

1. Перевод запроса в URL-схему, её исполнение с возможностью обработки отсутствия схемы.
2. Обработка схемы и навигация внутри приложения к заданному разделу/экрану.

URL-схема (URL scheme) — часть URL до ://, ответственная за схему взаимодействия с ресурсом, на который ведет сама ссылка, в большинстве случаев имеется ввиду протокол.

Существует ряд зарегистрированных схем, к примеру http, ftp, tel, mailto, и т.д.

Создание, выполнение и обработка результата выполнения URL-схемы

Для правильной конвертации HTTP-запроса в URL-схему необходимо хранить на сервере таблицу соответствия и/или заданное правило перевода.

Способов правильно выполнить URL-схему и обработать результат существует несколько. Все зависит от того, из какой среды URL-схема выполняется. Если это происходит в iOS приложении, то существуют стандартные способы проверить, зарегистрирована ли URL-схема в системе:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@”myapp://”]];

Если же схема выполняется из веб-среды, то оптимально использовать JS-скрипт, который либо запустит приложение, либо отправит на нужный ресурс.

Пример:

$(function(){
    window.location = 'myapp://';
    setTimeout(function(){
        window.location = 'fallback.html';
    }, 500);
});

Если через 500 мс не выполнится переход по схеме “myapp://" (ранее сгенерированная схема), то будет осуществлен переход на “fallback.html”.

Данный скрипт необходимо встроить в ресурс, ответственный за переход.
На GitHub есть несколько более или менее удачных реализаций подобных решений.

Обработка полученной URL-схемы и навигация внутри приложения

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

Для этого, в первую очередь, необходимо зарегистрировать собственную URL-схему, которая будет проассоциирована с приложением.
В настройках основного таргета проекта в разделе Info необходимо добавить в пункте URL Types —URL тип вашей схемы (рис 2.)



В поле Identifier необходимо указать bundleID приложения, а в поле URL Schemes — схему, с которой будет связано ваше приложение. Дальше необходимо реализовать механизм навигации в приложении. Для этого надо обработать возможную передачу в приложение URL. Передать её можно многими способами, мы рассмотрим непосредственное исполнение схемы в системе.

Для того чтобы обработать запуск приложения через URL, надо в AppDelegate приложения в методе:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Из словаря lauchOptions достать объект по ключу UIApplicationLaunchOptionsURLKey. Если объект существует, это означает, что приложение запущено посредством URL-схемы и данную схему можно обработать. Если же приложение запущено в момент исполнения схемы, то URL надо извлекать в том же AppDelegate в методе:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

Здесь необходимо использовать параметр url для дальнейшей навигации. Навигация в приложении — выбор исключительно личный, но я рекомендовал бы использовать шаблон Router. Во-первых, это не нарушает принцип Single Responsibility, во-вторых, позволит инкапсулировать и в дальнейшем эту навигацию использовать из любого места. Роутер должен принимать в себя URL (как ключ) и выдавать ViewController или же эту навигацию осуществлять.

Сторонние решения


Из сторонних решений можно рассмотреть Mobile Deeplinking (AppURL, AppLinks, UrbanAirShip и т.д.), данные фреймворки являются полноценными решениями для реализации всех компонент технологии Deep Linking. Содержат отдельные библиотеки со своими обработчиками внешних URL и механизмом навигации в приложении. Соответственно, подобные решения требуют интеграции своих SDK в проект.

Отдельно стоит рассмотреть решение, которое не требует интеграции: Deep Link Me сервис предоставляющий возможность запускать приложение с определенной ссылкой, при этом в случае, если приложение не установлено, совершить редирект в магазин. Все настройки происходят непосредственно на сайте, из возможных опций:?
  • добавление правил соответствия «HTTP-запрос — URL-схема»;
  • переход на альтернативный ресурс, включая магазин приложений;
  • поддержка iOS/Android.

Единственное неудобство данного решения в том, что весь транзит происходит через deeplink.me, что несомненно увидит пользователь.? Для использования этого инструмента необходимо реализовать поддержку URL-схем и навигацию в приложении самостоятельно.

Новый взгляд на Deep Linking


Что нам предлагает Google в технологии глубокого связывания.

Совсем недавно Google стартовал новое направление App Indexing. Конечно, по большей части оно нацелено на Android-разработку и реализовано максимально удобно именно для нее, но и iOS осталась не забыта, правда в ограниченой beta-версии.

Итак:
Помимо работоспособного Deep Linking появилось еще и индексирование приложения в поисковой системе Google. В результате поиска во всемирной сети будут отображаться ссылки на разделы приложения.

Для реализации необходимо:

1. Зарегистрировать еще одну URL-схему в проекте в формате:
gsd-{scheme}
где, “scheme” — ваша схема, зарегистрированная выше.
2. Подключить фреймворк GoogleAppIndexing (можно через CocoaPods)
3. В вышеуказанных методах вашего приложения обработать переход следующим образом:
 NSURL *sanitizedURL = [GSDDeepLink handleDeepLink:url];

Это поможет связать ваше приложение c Google App Indexing и создаст панель для возврата в поиск.
4. Необходимо настроить ваш сайт, на который совершается переход. Для этого в хедер сайта надо добавить:
<html>
<head>
  ...
  <link rel="alternate" href="ios-app://{itunes_id}/{scheme}/{host_path}" />
  ...
</head>
<body> … </body>

Также можно дать доступ GoogleBot к вашему сайту для полноценного индексирования.

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

Как избежать подобных ситуаций?

И вновь Apple нас не разочаровывает — начиная с iOS 9 добавлена поддержка HTTP и HTTPS с прямым переходом в приложение.
В июне 2015 года на WWDC “парни из Купертино” рассказали нам о новом подходе к реализации такого удобного механизма промоутинга мобильного приложения.

Назвали они его Seamless Linking, что можно перевести как “бесшовные ссылки”. Данный механизм позволяет использовать те же самые веб URL, что и при переходе по разделам вашего сайта, кроме того, связь между приложением и веб ресурсом происходит через Bundle ID приложения, что дает этой связи уникальность, также вы можете указать те разделы сайта, которые представлены в вашем мобильном приложении, и Deep Linking будет работать только для них. Ну круто же!!!

Как это работает?


Ссылка обрабатывается в системе и из нее извлекается домен (или хост) и непосредственно путь, через который вы можете управлять навигацией в приложении:

https://n-pizza.com/margarita_new
n-pizza и является в данном случае доменом. Домен должен быть проассоциирован с приложением посредством специального файла, защищенного SSL-сертификатом, который хранится на сервере сайта. Называться он должен apple-app-site-association и содержать специальную JSON структуру.

{
    "applinks": {
        "apps" :[],
        "details":{
            “123456.npizza.com” :{
                "paths": ["*"]
        }
    }
}

Где 123456.npizza.com - app_bundle_id
“path” : [“*”] — говорит о том, что ваше приложение поддерживает все разделы веб-ресурса, в противном случае, вы можете указать, определенные пути:

{
    "applinks": {
        "apps" :[],
        "details":{
            “123456.npizza.com" :{
                "paths": ["/margarita_new",
                          "/old/greate_pizza/*"]
        }
    }
}

Далее созданный JSON необходимо подписать тем сертификатом, который используется на вашем веб-ресурсе, либо сгенерировать новый (допустимо использовать WildCard сертификат) подписать им JSON и добавить его на сервер. Сертификат, которым подписывается приложение в данном случае не используется.

Важно понимать, что для каждого домена должен быть уникальный apple-app-site-association файл

n-pizza.com/apple-app-site-association

В приложении необходимо установить ассоциации с доменами, которые вы поддерживаете в пункте “Associated Domains”, в настройках проекта. А универсальные ссылки необходимо обрабатывать в методе AppDelegate:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler

Где, тип активности для универсальных ссылок будет:

NSUserActivityTypeBrowsingWeb

Декомпозировать URL можно будет с помощью нативных средств, таких как: класс
NSURLComponents
или сторонних фреймворков, как Bolts от Facebook. Далее навигация должна происходить по уже известной схеме, изложенной выше.

В результате пользователь, переходя по ссылке, или оказывается на том ресурсе, куда эта ссылка вела, или в приложении. Огромный плюс этого решения в том, что URL-схемы не используются. Но не меньший минус, что решение только для iOS и только с 9 версии.

Контекстные Deep Linking


Все, что написано выше, прекрасно работает и дает необходимый эффект проникновения в приложение, только если приложение уже установлено. Если задуматься, то реальная польза будет для крупных компаний, чьи приложения установлены у большинства пользователей смартфонов, а их не больше 40-50 штук.

Если же приложение не установлено, а таких большинство в AppStore или Google Play, то пользователь окажется на странице сайта, либо в магазине приложений, что тоже не очень хорошо, т.к. после установки и запуска приложения будет показан главный экран. Любой из сценариев равносилен не работающему Deep Linking.

Для достижения полного эффекта работы Deep Linking существуют контекстные глубокие ссылки. Суть их работы заключается в том, что условие перехода в приложение (параметры в URL-схеме), по которому строится дальнейшая навигация, и идентификатор устройства сохраняются на серверной стороне. После установки и запуска приложения, это условие запрашивается и строится навигация. Для пользователя все выглядит аккуратно и бесшовно.

Можно реализовать данный подход совместно с любым вышеуказанным методом. Или воспользоваться готовым решением, встроив SDK.

Комментарии (6)


  1. ViPppp
    24.09.2015 10:30
    +1

    В iOS 9 стоит также помнить про LSApplicationQueriesSchemes.


    1. mihasia_84
      24.09.2015 16:40

      Да, конечно. Теперь уже поддержка iOS 9 SDK — обязательна :-)


  1. SamDark
    24.09.2015 14:43

    Гугл всё «испортил» и в Android теперь никак не получается сделать диплинки вида `myschema://something`, при клике на которые и отсутствии приложения грузилась бы fallback веб-страница. Ладно ещё для Chrome можно использовать intent-ы, но есть ещё Samsung browser, который дефолтный для огромного рынка телефонов соответствующей компании. Там fallback на URL, насколько я знаю, вообще невозможен.


    1. mihasia_84
      24.09.2015 16:27
      +1

      Согласен. Мы недавно проводили исследование на эту тему и действительно — обработка кастомных URL-схем в Android отдана на откуп браузерам. Тут оптимально использовать App Indexing и дорабатывать Web-ресурсы исходя из возможностей этого инструмента. App Indexing


      1. SamDark
        24.09.2015 16:32

        Дык intent filters же не работает в Samsung-овском браузере…


        1. mihasia_84
          24.09.2015 17:35

          Результат нашего исследования:
          — не работает в браузере UC Browser на Android (По России 2.8%, По Москве 9.2%)

          Надо или искать workaround или принять как факт. :)

          Как одно из решений, которое частично помогает — оборачивать URL-схему в ссылку или кнопку, что бы схема не просто выполнялась, а выполнялась, как действие.