Pull to refresh

Universal Links в iOS на практике

Практически год прошел с WWDC 2015, где инженеры компании Apple представили новый подход к Deep Linking, но в сети так и не появилось хороших статей на этот счет — сейчас буду пробовать это исправить.

Что же нового придумали в Apple?


В iOS 9 была добавлена поддержка перехода в приложение по веб URL с http:// и https:// схемами — Seamless Linking (читаем как “бесшовные ссылки”). Т.е. пользователь просто нажимает на обычную ссылку на сайт, а попадает в приложение без открытия Safari. Если же приложения нет, то откроется браузер. Браузер же можно открыть и из приложения по нажатию кнопки, которая появится вместо индикатора заряда. Также можно открыть эту ссылку из самого приложения вызовом openURL. Более того, Вы можете указать какие разделы сайта в каком приложении открывать — и для всего этого не придется писать ни одной строки кода на сервере. Далее я подробно объясню, как все это настроить и избежать возможных граблей.

Часть 1. Cайт для тестирования


Т.к. зачастую у серверных разработчиков и «без нас куча дел» никто скорее всего помогать настраивать Applinks не будет — и не нужно, мы справимся без них. Я знаю два неплохих варианта, где можно получить себе домен и закинуть apple-app-site-association не заплатив ни цента: GitHub Pages и Google Cloud Platform. Очень интересно послушать другие варианты, но пока мы выбираем первый, т.к. тут будет всем привычный гитхаб, система контроля версий и, скорее всего, аккаунт в наличии.

Как создать такой репозиторий я писать не буду, инструкция очень проста (https://pages.github.com). На выхлопе я получаю пустой сайт по адресу bernikowich.github.io.

Часть 2. Настройка проекта


Создаем проект и выбираем как-нибудь Bundle Identifier, у меня это bernikowich.UniversalLinks. Выбираем команду с действующей подпиской на Apple Developer Program, в которой создастся Application ID в Member Center.



Далее открываем в настройках таргета Capabilities и включаем Assosiated Domains. На этом этапе в Member Center создастся AppID с указанным ранее Bundle Identifier. Далее указываем наш домен в таком формате applinks:{домен}, у меня получается applinks:bernikowich.github.io.

image

Часть 3. Самый простой файл apple-app-site-association


Теперь самое интересное, нужно создать файл для нашего сайта, из которого Apple будет доставать BundleID, пути по которым нужно открывать приложения и т.д… Сейчас я покажу самый простой вариант для этого:

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "3EFP2B895H.bernikovich.UniversalLinks",
        "paths": [
          "*"
        ]
      }
    ]
  }
}

Интересны тут всего 3 вещи:
1) Значение по ключу «apps» должно присутствовать и должно быть пустым массивом.
2) «appID» я получил из Member Center (далее будет скриншот где явно видно откуда взялась строка 3EFP2B895H и bernikovich.UniversalLinks.
3) «paths» определяет пути, по которым iOS будет открывать вместо сайта приложение с заданным appID.

Далее мы сохраняем это файл в корень репозитория сайта. Обратите внимание на то, что у файла нет расширения — просто apple-app-site-association. Пушим все на github.

Часть 4. Обработка URL'ов


Сейчас мы возвращаемся к Xcode проекту. Найдите файл имплементации делегата (по умолчанию: AppDelegate.m) и добавьте там следующий метод:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURLComponents *URLComponents = [NSURLComponents componentsWithURL:userActivity.webpageURL resolvingAgainstBaseURL:YES];
        NSLog(@"%@", URLComponents.path);
    }
    return YES;
}

Сейчас мы лишь добавили метод, который будет вызван после запуска приложения (или перехода в foreground). Метод выведет путь из линки. Для обработки URL'ов советую пользоваться NSURLComponents, который был представлен в iOS 7.

Отправьте себе на почту или сохраните в заметках ссылку с со своим доменом, например такую: bernikowich.github.io/index.php. Теперь можете установить и запустить приложение на девайсе (Applinks не будет работать на симуляторе!). Если вы сделали все верно, то после проделанных действий у вас должно открываться приложение по нажатию на ссылку из почты или заметок, при это в логах будет что-то типа:

2016-03-04 15:39:04.898 UniversalLinks[619:169698] /index.html

Часть 5. Интересности с apple-app-site-association


Что если открывать в приложении нужно лишь некоторые разделы или вовсе отдельные страницы? Для всего этого есть специальные символы в разметке:

  • Если приложение поддерживает все разделы сайта используйте просто *
  • Указать определенную линку можно написав /news/latest/
  • Указать раздел можно используя * как символ определяющий любую подстроку. Например /*/latest/ либо /videos/*
  • Для подстановки любого одного символа ?. Пример: /videos/201?/

Обратите внимание, что пути чувствительны к регистру.

Немного тонкостей. Задача следующая: нужно открывать в приложении видео (/videos/cats/video1), но не открывать разделы (/videos/cats). Пишем в файле apple-app-site-association такой путь:

"/videos/*/*"

Казалось бы все ОК, но не тут то было. Пути формата /videos/2014 все равно открываются в приложении. Решилось все добавлением в конце еще одного слеша:

"/videos/*/*/"

Объяснения этому пока не найдено, но возможно решение поможет кому-то еще.

Выводы


Universal Links отличная вещь, уход от «швов» делает переходы к приложению по ссылке намного проще и красивее. Общие ссылки на сайты и приложения определенно шаг вперед, а подход к определению ответственных приложений защищен от недобросовестных разработчиков.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.