и Firebase делают это бесплатно. Эти продукты, особенно Branch, ориентированы на обработку всех этих крайних случаев, так что вам не нужно. Нет причин создавать все это самостоятельно, когда он уже открыт.

ом много учебных пособий по Deep Linking (Universal Links или App Links). Но большинство из них показывает, как включить его в приложениях для Android или IOS. Также есть платные облачные решения, но они предлагают много возможностей. Но в реальной жизни я столкнулся с тремя основными проблемами:

Некоторые браузеры не позволяют ссылкам на приложения работать. Например, вы можете настроить http://example.com для отслеживания в приложении, но если пользователь щелкает эту ссылку через приложение Facebook, она не обрабатывается, и браузер Facebook отображает веб-сайт.Не существует единого стандартного решения для обработки ссылок для приложений Android и IOS.Нет практического решения, если приложение не установлено на мобильном устройстве и пользователь щелкает ссылку приложения.

Я написал этот Q & A, который является результатом моих исследований (потраченных слишком много часов), чтобы иметь уникальное и работающее для всех случаев решение.

Коды приходят из моего рабочего решения, но я удалил некоторые части, чтобы показать идею. Если есть проблемы с компиляцией, следуйте алгоритму и напишите свой собственный код

Вот решение, делайте шаг за шагом, даже если вы знаете некоторые шаги, потому что в кодах есть хитрости. Также некоторые пояснения приведены в строках комментариев частей кода, пожалуйста, прочитайте их.

Примерами являются обработка ссылки http://example.com/v/ по ссылкам в ваших приложениях для Android и IOS с аргументом в конце, например, http://example.com/v/id-of-user?key=value.

1. Настройка Android

1.1 Добавьте информацию об активности в ваш файл AndroidManifest.xml:

<activity
android:name=".appLinkHandlerActivity">

<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:host="example.com"
        android:pathPrefix="/v/"
        android:scheme="http" />
</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" />

<!—this intent is needed to handle links to myapp://share, I will explain later why we need it -->
    <data
        android:host="share"
        android:scheme="myapp" />
</intent-filter>

1.2 Создайте действие с именем appLinkHandlerActivity, которое будет обрабатывать ссылки, на которые нажали

    public class appLinkHandlerActivity extends AppCompatActivity {


    /* assume that user is clicked http://example.com/v/my-user-id   
    actCode will be “v”, pCode will be “my-user-id” */
    String actCode="", pCode="";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        // ATTENTION: This was auto-generated to handle app links.
        Intent appLinkIntent = getIntent();
        String appLinkAction = appLinkIntent.getAction();
        Uri appLinkData = appLinkIntent.getData();



        String code = null;
        try {
            code = getIntent().getData().getLastPathSegment();
        } catch (Exception e) {

        }

        if (code == null) {
            Intent i = new Intent(this, {your main activity.class});
            startActivity(i);
        }

        List<String> params=appLinkData.getPathSegments();


        if (params.size()>0)
            actCode=params.get(0);

        if (params.size()>=2)
            pCode=params.get(1);

        /* assume that user is clicked http://example.com/v/my-user-id actCode is “v”, pCode is “my-user-id”  Do now whatever you need. */
    } 
 }

2. Настройка IOS

Это сложнее, чем Android, я объясню необходимые моменты здесь. Пожалуйста, обратитесь к документам:https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1

https://www.raywenderlich.com/128948/universal-links-make-connection

2.1 Вы должны включить связанные домены при создании идентификатора приложения на портале разработчика Apple. Важная проблема: вам нужно иметь приобретенную учетную запись Apple Developer, чтобы включить эту опцию, то есть, не покупая учетную запись разработчика, вы не можете попробовать AppLinks в своем проекте IOS.

2.2 В проекте XCode откройте вкладку «Capabilites» и переключите Связанные домены на «Вкл». Если вы не включили «Связанные домены» в разделе «Идентификатор приложения Apple Developer Portal», это может быть недоступно для добавления. Чтобы добавить разрешение, нажмите кнопку «+» в разделе «Связанные домены» и напишите «applinks: example.com».

2.3 Создайте файл на своем веб-сервере с именем «apple-app-site-association», и этот файл должен быть доступен через https://example.com/apple-app-site-association. HTTPS является обязательным, и если он недействителен Ссылка на приложение сертификата SSL может не работать. Добавьте следующие строки в файл apple-app-site-association:

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "6HY7TF56.com.example.app",
                "paths": [ "/ios/*", "/v/*" ]
            }
        ]
    }
}

appID - это формат {«Team ID». «Bundle ID вашего приложения»}. Вы можете найти свой teamID в разделе «Сведения о членстве» на портале разработчика.

Мы обрабатываем ссылку http://example.com/v/parameters, но здесь вы видите, что есть другая конфигурация пути для «/ ios / *». Нужно обходить неподдерживаемые браузеры, я объясню позже.

2.4 В файле AppDelegate.m добавьте два метода для обработки пользовательских кликов на example.com.

-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
    if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {

        NSURL *url = userActivity.webpageURL;
          [self parseUrl:url];

    }
return YES;
}


- (void) parseUrl:(NSURL * )handledUrl {
    NSString *urlStr=@"";
    NSString *pCode=@"";
    NSString *handledUrlStr=[handledUrl parameterString];

    NSString *handledUrlQueryPart;

    NSArray<NSString *> *pathsArray= [handledUrl pathComponents];

    //remember that we only added paths “/v/*” and “/ios/*” to handle in apple-app-site-association file. If you want to handle more subpaths you can add them into apple-app-site-association file, then below if-else conditions. Don’t touch to config and code for “/ios/*” path, it is needed to bypass unsopported browsers.
    if ([pathsArray[1]  isEqual: @"v"]){
        //sample url= http://example.com/v/menu?aaa=bbb
        pCode = pathsArray[2];
        handledUrlQueryPart=[handledUrl query];
    } else if ([pathsArray[1]  isEqual: @"ios"]){
        //sample url= http://example.com/ios/deeplink-ios.php?/v/menu?aaa=bbb
        NSArray *uriArray = [[handledUrl query] componentsSeparatedByString:@"?"];
           NSArray *queryPathsArray = [uriArray[0] componentsSeparatedByString:@"/"];
        if ([queryPathsArray count] > 2)
            pCode = queryPathsArray[2];

        if ([uriArray count] > 1 ){
            handledUrlQueryPart=uriArray[1];
        }
    }

    /* here pCode is the parameter what is passed from user. If the link clicked is http://example.com/v/menu it is “menu”. If the link clicked is http://example.com/v/menu?aaa=bbb it is “menu?aaa=bbb”. So you can do now what ever you need. */    
}

3. Управление необработанными кликами.

3.1 Хорошо, ваши приложения для Android и IOS должны обрабатывать щелчки по ссылке http://example.com/v/blabla и передавать параметр «blabla» в переменную pCode, использованную в показанных мной методах. Но некоторые брови, такие как приложение Facebook, могут отключать ссылки на приложения для работы. В этом случае пользователь нажимает на ваш веб-сервер, и браузер пытается показать содержимое http://example.com/v/blabla, которое, вероятно, 404 Page Not Found. Для обработки этих кликов мы настроим веб-сервер Apache и перенаправим пользователей в ваше приложение. Если вы используете IIS или другой, я не знаю, как это сделать, но вы можете взять это в качестве образца и использовать тот же алгоритм для настройки вашего веб-сервера.

3.2 Запишите приведенные ниже строки в файл .htaccess в корневом каталоге example.com

#redirect to deeplink
<IfModule mod_rewrite.c>

#if there is a request to example.com/v/any-sub-path, redirect them to example.com/deeplink.php file. This rule is for both IOS and Android
RewriteRule ^(v)/.* /deeplink.php [L]

#if there is a request to example.com/ios/any-sub-path, redirect them to app installation page. That means your app is not installed on IOS device. This rule is for IOS devices only
RewriteRule ^(ios)/.* http://itunes.apple.com/install-of-your-app [L] 
</IfModule>  

4. Перенаправлять пользователей в приложения

4.1 Правила перенаправления в файле .htaccess, показанном на шаге 3, перенаправляют пользователей в файл deeplink.php. Итак, вот содержимое этого файла для перенаправления пользователей в ваше приложение.

 <?php

$request_uri=$_SERVER[REQUEST_URI];

$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
if(stripos($ua,'android') == true){
//if user device is android, redirect it to intent url which is handled by Android.
        $redir_tag="<meta http-equiv='refresh' content='0;url=intent://share$request_uri/#Intent;scheme=myapp;S.browser_fallback_url=http%3A%2F%2Fexample.com%2Fget-app%2F;package=com.example.app;end' />";
//scheme=myapp and host named “share” is configured in AndroidManifest.xml file to be handled by the activity.
//fallback url is the url, if your app is not installed on android device, so you can redirect them to a page to install android app. In some cases users are redirected to Play Store directly for application id of com.example.app
}

else if ( (stripos($ua,'iPhone') == true) || (stripos($ua,'iPad') == true) ) {
        //if user device is IOS, redirect them to a web page to see. There will be a link here to the another handled link: http://example.com/ios/blabla.
        // due to my experience there is no way to redirect IOS to app directly at this stage, user must click a link on browser and that link must be different than the link which was shown and clicked at first.
        // another experience taught me ther ecan be problems if we redirect users to a web page under example.com which is configured as applink, so I redirect users to a page under deep.example.com here
        $redir_tag="<meta http-equiv='refresh' content='0;url=http://deep.example.com/deeplink-ios.php?$request_uri' />";
}

else {
//If the device is neither IOS nor Android, redirect users to a web page which gives information that this link is for Android and IOS only
        $redir_tag="<meta http-equiv='refresh' content='0;url=http://example.com/non-mobile' />";
}


?>



<html>
    <head>

        <!— add tags for no-caching, this is important, the date below is my son’s birth time and date, he is now 6, so you can use it as a date in the past -->
        <meta http-equiv="cache-control" content="max-age=0" />
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="-1" />
        <meta http-equiv="expires" content="Tue, 31 May 2011 10:15:00 GMT+3" />
        <meta http-equiv="pragma" content="no-cache" />


        <?php echo $redir_tag; ?>

    </head>
</html>

5. Покажите пользователям IOS ссылку для нажатия

5.1 Вот содержимое файла http://deep.example.com/deeplink-ios.php. Пользователи увидят страницу, подобную приведенной ниже, когда они нажмут на ссылку, этот запрос должен быть обработан вашим приложением IOS.

<?php
//we create a link to http://example.com/ios/… which is configure to be handled by IOS app. IOS needs to be a user click in some cases to handle the request, that is why this page is shown to the user
$request_uri=$_SERVER[REQUEST_URI];
$link="<div class='w3-container w3-card'><h1><a href='http://example.com/ios$request_uri'>Click here to open MyApp</a></h1></div>";
?>

<html>
    <head>

        <!—adding no-cache tags is also important here-->
        <meta http-equiv="cache-control" content="max-age=0" />
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="-1" />
        <meta http-equiv="expires" content="Tue, 31 May 2011 10:15:00 GMT+3" />
        <meta http-equiv="pragma" content="no-cache" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3mobile.css">

    </head>
<body>

<?php echo $link ?>

</body>
</html>

6. Анализ ситуации:

6.1 Android

6.1.1 Case-1 - приложение установлено на устройстве
• запросы браузера для http://example.com/v/blabla
• Android ловит ссылку и создает действие, настроенное в вашем файле манифеста

6.1.2 Case-2 - приложение установлено на устройстве
• запросы браузера для http://example.com/v/blabla
• Android не может поймать ссылку.
• Браузер подключается к веб-серверу, запросить / v / blabla
• Он перенаправлен в deeplink.php? / V / blabla из-за конфигурации в файле .htaccess
• deeplink.php узнает, что это android, и перенаправляет на: intent: // share / v / blabla / # Intent; схема = myapp; S.browser_fallback_url = http% 3A% 2F% 2Fexample.com% 2Fget-app% 2F; пакет = com.example.app
• Android перехватывает запрос для intent: //, поэтому из-за конфигурации в файле манифеста myapp: // share / v / blabla обрабатывается действием

6.1.3 Case-3 - приложение не установлено
• запросы браузера для http://example.com/v/blabla
• Android не может поймать ссылку.
• Браузер подключается к веб-серверу, запросить / v / blabla
• Он перенаправлен в deeplink.php? / V / blabla из-за конфигурации в файле .htaccess
• deeplink.php узнает, что это android, и перенаправляет на: intent: // share / v / blabla / # Intent; схема = myapp; S.browser_fallback_url = http% 3A% 2F% 2Fexample.com% 2Fget-app% 2F; пакет = com.example.app
• Android перехватывает запрос для intent: //, но для id: com.example.app не установлено приложение. В некоторых случаях он ошибается и перенаправляет браузер на http://example.com/get-app или на страницу установки Play Store вашего приложения.

6.2 IOS

6.2.1 Case-1 - приложение установлено на устройстве
• запросы браузера для http://example.com/v/blabla
• IOS перехватывает ссылку и вызывает метод continueUserActivity в AppDelegate.m

6.2.2 Case-2 - приложение установлено на устройстве
• запросы браузера для http://example.com/v/blabla
• IOS не может поймать ссылку.
• Браузер подключается к веб-серверу, запросить / v / blabla
• Он перенаправлен в deeplink.php? / V / blabla из-за конфигурации в файле .htaccess
• deeplink.php узнает, что это IOS, и перенаправляет на: http://deep.example.com/deeplink-ios.php?/v/blabla
• файл deeplink-ios.php показывает URL-адрес пользователя. URL-адрес: http://lify.me/ios/v/blabla
• Пользователь щелкает URL-адрес и браузер запрашивает http://lify.me/ios/v/blabla
• IOS перехватывает запрос из-за конфигурации пути «/ ios / *» в файле apple-app-site-association и вызывает метод continueUserActivity в AppDelegate.m
• Если IOS по какой-либо причине не может перехватить запрос на http://lify.me/ios/v/blabla, он будет работать, так как приложение не установлено на устройстве. Посмотри на это дело.

6.2.3 Case-2 - приложение не установлено на устройстве
• запросы браузера для http://example.com/v/blabla
• IOS не может поймать ссылку.
• Браузер подключается к веб-серверу, запросить / v / blabla
• Он перенаправлен в deeplink.php? / V / blabla из-за конфигурации в файле .htaccess
• deeplink.php узнает, что это IOS, и перенаправляет на: http://deep.example.com/deeplink-ios.php?/v/blabla
• файл deeplink-ios.php показывает URL-адрес пользователя. URL-адрес: http://lify.me/ios/v/blabla
• Пользователь щелкает URL-адрес и браузер запрашивает http://lify.me/ios/v/blabla
• Если IOS не может поймать запрос на http://lify.me/ios/v/blabla
• Браузер подключается к веб-серверу, запросить / ios / v / blabla
• Он перенаправлен на http://itunes.apple.com/install-of-your-app из-за конфигурации в файле .htaccess на веб-сервере.

6.3 Ссылка на приложение нажимается на устройстве, отличном от Android или IOS
• запросы браузера для http://example.com/v/blabla
• ОС устройства не может поймать ссылку.
• Браузер подключается к веб-серверу, запросить / v / blabla
• Он перенаправлен в deeplink.php? / V / blabla из-за конфигурации в файле .htaccess
• deeplink.php узнает, что это ни IOS, ни Android, и перенаправляет на: http://example.com/non-mobile

Ответы на вопрос(0)

Ваш ответ на вопрос