Deep Linking или App Links - способ указать приложению что его хотят открыть на определенной странице.
Пример такой ссылки mydeeplinkscheme://mydeeplinkhost/path?arg1=value1
iOS
Для того что бы зарегистрировать приложение на схему нужно в Info.plist добавить
<dict> . . . <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>mydeeplinkscheme</string> </array> <key>CFBundleURLName</key> <string>My Deeplink Scheme</string> </dict> </array> </dict>
Как правильно заполнять CFBundleURLName вопрос открытый, в документации написано следующее:
A string containing the abstract name of the URL scheme. To ensure uniqueness, it is recommended that you specify a reverse-DNS style of identifier, for example, com.acme.myscheme. The string you specify is also used as a key in your app’s InfoPlist.strings file. The value of the key is the human-readable scheme name.В приложении ссылку можно получить в двух случаях: при старте приложения по глубокой ссылке в методе FinishedLaunching, а если приложение уже запущено тогда в HandleOpenURL.
public override bool FinishedLaunching (UIApplication app, NSDictionary options) { NSObject urlObject; if (options.TryGetValue(UIApplication.LaunchOptionsUrlKey, out urlObject)) { var url = urlObject as NSUrl; if (url != null) { OpenDeepLink(url); } } } public override bool HandleOpenURL (UIApplication application, NSUrl url) { OpenDeepLink(url); return true; } void OpenDeepLink(NSUrl deepLink) { . . . }
После тестирования я отказался от обработки ссылки в методе FinishedLaunching, у меня HandleOpenURL вызывался даже если приложение не было запущено.
Android
Нужно в AndroidManifest.xml добавить следующее
<activity android:name="com.package.name.DeeplinkingActivity"> <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="mydeeplinkscheme" /> <data android:host="mydeeplinkhost" /> <!-- можно без этой строки --> </intent-filter> </activity>
Если хост не указывать тогда ссылки не будут фильтроваться по хосту. Указывать хост может быть полезно для случая когда мы хотим подписаться на популятную схему, например http. Скажем есть каталог сайт и приложение, с одинаковым содержимым. Тогда открывая на сайт в браузере выскочит предложение открыть приложение.
В Xamarin правильно заполнить манифест проще всего через аттрибуты. Фильтров может быть несколько.
[Activity()] [IntentFilter(new[] { Android.Content.Intent.ActionView }, DataScheme = "mydeeplinkscheme", Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })] [IntentFilter(new[] { Android.Content.Intent.ActionView }, DataScheme = "http", DataHost = "mycatalog.com", Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })] class DeeplinkingActivity { . . . }
Я использую отдельное активити для получения ссылок в котором решаю что запускать следующее, но можно для каждой схемы/хоста использовать свою активити.
Ссылка приходит в метод OnCreate указанного активити, в моем примере DeeplinkingActivity
override protected void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (Intent != null && Intent.Data != null) { OpenDeepLink(Intent.Data); } Finish(); } void OpenDeepLink(Android.Net.Uri deepLink) { . . . }
Еще один раздел
Такие ссылки работают в стандартном браузере если они расположены на странице и по ним нажать пальцем. Если ссылку ввести в адресную строку, то браузер открывает поисковик с этой строкой. Также если такую ссылку послать по почте то она не подсвечивается (или может не подсвечаваться) даже если письмо отправлено как HTML.
Я решил эти мелочи добавлением HTTP прокси сервера, который делает редирект HTTP/1.1 302 Found Location: mydeeplinkscheme://blah/blah
А HTTP ссылку уже можно вводить в адресную строку браузера и посылать по почте.
Вывод
Как видно использовать глубинные ссылки достаточно легко.
Разобрать ссылку и открыть нужную страницу это уже дело техники.
Best wishes
And happy coding!