В мире Android и iOS разработки есть механизм диплинков. Диплинк представляет из себя обычную ссылку, при переходе на которую у вас открывается приложение (если таковое имеется) и зачастую показывается определенный контент. В диплинки мы можем добавлять различные параметры, поскольку это просто ссылка (например, id видео, код подтверждения и т.д.). В этой статье мы разберемся, как заимплементить диплинки для нашего Флатер приложения для двух платформ: Android и iOS.
Где применяются диплинки?
Старт приложения на определенном контенте - ссылка на ютуб видео стартует приложение и открывает определенное видео. Стоит упомянуть, что при уже запущенном приложении, новое не будет стартовать, а видео откроется в текущей сессии.
Восстановление пароля - стартует приложение с окном на уровне "Введите новый пароль"
Любой другой юзкейс, когда надо стартовать приложение (или во время текущей сессии) и добавить какое-то поведение на основе параметров в диплинке
Навигация по приложению (в качестве основного способа навигации такой вариант не совсем рациональный)
Во флатере нет единого решения для добавления диплинков, поскольку это платформозависимый механизм и необходимо это реализовывать отдельно для двух платформ. Далее последовательно рассмотрим перехват нашим приложением диплинков на Android и iOS системах и их обработку в флатер приложении.
Android
В Android есть 2 типа ссылок, открывающих приложение - Deep Links и App Links.
Внешние отличия: Deep Links могут иметь кастомную схему либо схему http, а App Links имеют исключительно схему https:
http://habr.com и awesome-scheme://habr.com - Deep Links
https://habr.com - App Link
Также важно уточнить, что при открытии App Link нас сразу перекинет в приложение, а при открытии же Deep Link появится похожее окошко с выбором приложения, в котором эту ссылку и открыть:
Внутренние отличия:
Реализация App Links требует наличие google-developer аккаунта и сайта со схемой https вместе с размещением на нем файла-конфигурации assetlinks.json
При отсутствии приложения, обрабатывающего такую ссылку, в случае Deep Link откроется ссылка в браузере по этому пути, в случае App Link - откроется ссылка на это приложение в Play Market'е.
Android Deep Links
В файле android/app/src/main/AndroidManifest.xml внутри <activity>...</activity> необходимо добавить следующий intent-filter:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="my-scheme"
android:host="my-host.com"
android:pathPrefix="/my-prefix" />
</intent-filter>
android:scheme - указывается кастомная схема либо http
android:host - указывается имя хоста
android:pathPrefix - опциональный параметр
Такой интент фильтр будет открывать наше приложение для ссылок вида my-scheme://my-host/my-prefix и my-scheme://my-host/my-prefix*
Чтобы протестировать, что все работает верно, можно ввести в консоль следующую команду:
adb shell am start -a android.intent.action.VIEW -d "my-scheme://my-host.com/my-prefix" your-app-package-name
Android App Links
Для начала необходимо подписать приложение и зарегистрировать его в Google Play Console (необходимо иметь платный google-developer аккаунт). Откуда в project-name->setup->app-integrity можно найти необходмый sha-ключ для конфиг-файла.
Сам конфиг файл выглядит следующим образом, только вместо com.example необходимо вставить свой package-name и вместо 14:6D* необходимо вставить свой sha-ключ:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
Потом необходимо добавить файл-конфигурацию на наш сайт с https-схемой. Если сайта нет, можно создать свой посредством сервисов firebase-deploy, heroku или github-pages.
Создаем новую папку .well-known в корне нашего сайта и добавляем туда файл assetlinks.json, чтобы перейдя по ссылке https://my-host.com/.well-known/assetlinks.json можно было посмотреть содержимое этого файла.
В файле android/app/src/main/AndroidManifest.xml внутри <activity>...</activity> необходимо добавить следующий intent-filter:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="my-host.com" />
</intent-filter>
android:scheme - указывается https
android:host - указывается имя существующего хоста
android:pathPrefix - опциональный параметр, как в Deep Links
Чтобы протестировать, что все работает верно, можно ввести в консоль следующую команду:
adb shell am start -a android.intent.action.VIEW -d "https://my-host.com" your-app-package-name
iOS
В iOS также есть 2 типа ссылок: Custom Scheme Links и Uni Links.
Они очень схожи с Deep Links и App Links в андроиде, но Custom Scheme Links могут иметь только кастомные схемы (как неудивительно), а Uni Links только схемы http и https.
http://habr.com и https://habr.com - Uni Links
awesome-scheme://habr.com - Custom Scheme Link
Внутренние отличия такие же, как для андроидовских линков: необходимо наличие apple-developer аккаунта и сайта с https схемой вместе с конфиг файлом apple-app-site-association для реализации Uni Links + при отсутствии приложения на девайсе ссылка откроется в браузере для Custom Scheme Links и откроется ссылка на приложение в AppStore для Uni Links.
iOS Custom Scheme Links
Для добавления ссылок с кастомными схемами нам достаточно зайти в Xcode и добавить список схем(не http и https), которое приложение может отлавливать:
Чтобы протестировать, что все работает верно, можно ввести в консоль следующую команду:
xcrun simctl openurl booted awesome-scheme://any-text
В данном случае нам хватает указать только схему, потому что исключительно на нее смотрит система при открытии приложения.
iOS Uni Links
Необходим apple-developer аккаунт.
Для начала необходимо добавить соответствующее разрешение в консоли разработчика - Identifiers-> Associated Domains - enabled.
Затем в Xcode добавить Capabilities->Associated Domains и новый домен, имеющий тип applinks и содержащий имя хоста. После добавления должны сгенерироваться файлы Runner.entitlements, RunnerDebug.entitlements, RunnerRelease.entitlements.
Остался последний шаг - добавить конфиг файл apple-app-site-association на наш сайт в папку .well-known, как и в случае с assetlinks.json.
Сам конфиг-файл имеет следующий вид:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "<TeamId>.<BundleId>",
"paths": [ "*" ]
}
]
}
}
Чтобы протестировать, что все работает верно, можно ввести в консоль следующую команду:
xcrun simctl openurl booted https://my-host.com
Обработка диплинков в приложении
Для обработки будем использовать плагин uni_links.
Диплинки мы можем получить в двух состояниях: когда приложение активно (Incoming deep links) и когда приложение убито (Initial deep links).
uni_links предоставляет нам два основных компонента - linkStream, по которому мы будем получать диплинки в уже стартовавшем приложении, и метод getInitialLink, через который мы получаем диплинк, стартовавший приложение.
Весь код обработки таких случаев:
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
@override
void initState() {
super.initState();
handleIncomingDeepLinks();
handleInitialDeepLink();
}
void handleIncomingDeepLinks() {
linkStream.listen((link) {
print(link);
});
}
Future<void> handleInitialDeepLink() async {
final link = await getInitialLink();
if (link != null) {
print(link);
}
}
@override
Widget build(BuildContext context) {
return const Scaffold();
}
}
Заключение
С большим удовольствием отвечу на появившиеся вопросы. Это моя первая статья на Хабре, и любая обратная связь будет очень полезной!