Что это?
Один из способов увеличения конверсии при продвижении 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)
SamDark
24.09.2015 14:43Гугл всё «испортил» и в Android теперь никак не получается сделать диплинки вида `myschema://something`, при клике на которые и отсутствии приложения грузилась бы fallback веб-страница. Ладно ещё для Chrome можно использовать intent-ы, но есть ещё Samsung browser, который дефолтный для огромного рынка телефонов соответствующей компании. Там fallback на URL, насколько я знаю, вообще невозможен.
mihasia_84
24.09.2015 16:27+1Согласен. Мы недавно проводили исследование на эту тему и действительно — обработка кастомных URL-схем в Android отдана на откуп браузерам. Тут оптимально использовать App Indexing и дорабатывать Web-ресурсы исходя из возможностей этого инструмента. App Indexing
SamDark
24.09.2015 16:32Дык intent filters же не работает в Samsung-овском браузере…
mihasia_84
24.09.2015 17:35Результат нашего исследования:
— не работает в браузере UC Browser на Android (По России 2.8%, По Москве 9.2%)
Надо или искать workaround или принять как факт. :)
Как одно из решений, которое частично помогает — оборачивать URL-схему в ссылку или кнопку, что бы схема не просто выполнялась, а выполнялась, как действие.
ViPppp
В iOS 9 стоит также помнить про LSApplicationQueriesSchemes.
mihasia_84
Да, конечно. Теперь уже поддержка iOS 9 SDK — обязательна :-)