Усі статті
mobiledeep linksiOSAndroid

Тестування мобільних діплінків із тунелем localhost

Universal Links на iOS та App Links на Android обидва вимагають JSON-файл, що віддається через HTTPS із кореня вашого домену. iOS хоче /.well-known/apple-app-site-association. Android хоче /.well-known/assetlinks.json. localhost не може віддати жоден через ім’я хоста, яке ОС пов’яже з вашим застосунком. Тож тунелюємо.

Реальна вимога на кожній платформі

iOS Universal Links

ОС завантажує https://ваш-домен.com/.well-known/apple-app-site-association (або /apple-app-site-association) при встановленні застосунку. Звіряє вміст із entitlement associated-domains вашого застосунку. Завантаження має пройти через справжній HTTPS. iOS не довіряє для цього самопідписаним сертифікатам і не довіряє localhost.

Android App Links

Android верифікує App Links, завантажуючи https://ваш-домен.com/.well-known/assetlinks.json. Файл має перелічувати SHA-256-відбитки вашого застосунку. Верифікація відбувається при встановленні та першому запуску. Те саме обмеження: справжній HTTPS, справжній домен.

Чому localhost не може це напряму

Навіть коли mkcert дає довірений HTTPS у браузері ноутбука, мобільна ОС не довіряє вашому локальному CA. І домен у apple-app-site-association має збігатися з associated-domain в entitlement застосунку — це справжній, розв’язуваний через DNS домен, а не localhost.

Деякі команди обходять це виділеним staging-доменом. Це працює, але цикл ітерацій повільний. localhost-тунель дає справжній HTTPS-URL на справжньому піддомені, до якого мобільні пристрої дістаються без скарг.

Як це під’єднати

  1. Віддавайте apple-app-site-association та assetlinks.json з локального dev-сервера за шляхом /.well-known/. Обидва файли. Обидва маршрути.
  2. Виконайте npx portpreview 3000 (або порт, який використовує ваш dev-сервер).
  3. Запишіть ім’я хоста тунелю — щось на кшталт abc123.portpreview.dev.
  4. В entitlement associated-domains вашого iOS-застосунку додайте applinks:abc123.portpreview.dev. В intent-filter Android — той самий хост.
  5. Зберіть і встановіть застосунок на реальний пристрій (симулятори мають дивну поведінку Universal Link).
  6. Відкрийте URL з іншого застосунку — Нотатки, Пошта, QR-код — і спостерігайте, як він спрямовується у встановлений застосунок замість браузера.

Підступ тунелювання для діплінків: ім’я хоста тунелю змінюється між сесіями, якщо немає зарезервованого піддомену. Кожна ротація означає перезбірку застосунку з новим записом associated-domain. Якщо часто ітеруєте поведінку діплінків, заведіть зарезервований піддомен.

Content-type важливий для apple-app-site-association

iOS очікує файл без розширення і або content-type application/json (новіший iOS), або application/pkcs7-mime (старий, підписаний формат). Майже всі сучасні застосунки використовують простий JSON-варіант. Переконайтеся, що dev-сервер повертає правильний content-type, інакше iOS мовчки відхилить файл без корисної помилки.

Спершу протестуйте з десктоп-браузера: відкрийте https://ваш-тунель.portpreview.dev/.well-known/apple-app-site-association й переконайтеся, що JSON рендериться, а заголовок content-type у dev tools правильний. Якщо ні, полагодьте перед полюванням на баги Universal Link у симуляторі.

Інші пастки налагодження діплінків

Невідповідність entitlement застосунку

Якщо ваш entitlement associated-domains каже applinks:abc.portpreview.dev, а apple-app-site-association перелічує def.portpreview.dev, iOS не завантажує. Ім’я хоста має бути узгодженим.

Universal Link зсередини Safari

Тап по Universal Link усередині Safari (того самого застосунку, де відкрита вкладка) іноді відкриває в Safari замість застосунку. Це навмисно — iOS запобігає трюку «відкрити застосунок щоразу, коли користувач натискає посилання». Тестуйте з Нотаток або Пошти.

Android App Links і digital asset links

Android також підтримує кастомні URL-схеми (вашзастосунок://шлях), яким не потрібні HTTPS чи assetlinks.json. Їх простіше тестувати, але вони менш безпечні — будь-який застосунок може зареєструвати ту саму схему. Для діплінкінгу продакшен-якості відповідь — App Links.

Наш процес мобільного тестування

Для проєкту, що випускає і iOS, і Android із діплінками:

  1. Запустіть бекенд, що віддає файли .well-known.
  2. Тунелюйте його через npx portpreview 3000.
  3. Щойно URL тунелю стабільний для сесії (або використайте зарезервований піддомен), оновіть записи associated-domain застосунку й зберіть.
  4. QA на фізичних пристроях — і свіжі встановлення, і оновлення.
  5. Для комбо OAuth-і-діплінк (провайдери входу, що редиректять назад у застосунок) поєднайте це з тестуванням OAuth-колбеків.

Налаштування дратує першого разу. Після цього URL тунелю — просто ще одна env-змінна у схемі Xcode та Gradle.

Про ширші патерни мобільного тестування див. мобільне тестування з тунелем localhost. Приєднайтеся до списку очікування PortPreview.

Поширені запитання

Чи можна тестувати iOS Universal Links на localhost?
Не напряму. Universal Links вимагають, щоб iOS завантажував apple-app-site-association через справжній HTTPS зі справжнього домену. localhost не підходить. Тунель дає HTTPS-URL на піддомені тунелю, який iOS пов’яже з вашим застосунком, щойно ви вкажете його в entitlement associated-domains.
Який content-type має використовувати apple-app-site-association?
Сучасний iOS очікує application/json. Старіші версії також приймали application/pkcs7-mime для підписаних файлів. Більшість застосунків сьогодні використовують простий JSON-варіант. Якщо iOS не підхоплює файл, спершу перевірте заголовок content-type з десктоп-браузера.
Чи потрібен Android App Links тунель для локального тестування?
Так, якщо хочете повну верифікацію App Link (не кастомні URL-схеми). Android завантажує assetlinks.json через справжній HTTPS із домену у вашому intent-filter. Тунель надає справжній HTTPS-URL на домені, який пристрій може верифікувати. Кастомним схемам це не потрібно, але вони менш безпечні.