La soluzione Deeplink per le app IOS e Android funziona su Facebook

Esistono troppe esercitazioni di Deep Linking (collegamenti universali o collegamenti di app). Ma la maggior parte di questi mostra come abilitarlo nelle App per Android o IOS. Inoltre ci sono soluzioni cloud a pagamento ma offrono molte funzionalità. Ma ci sono tre problemi principali che ho affrontato nella vita reale:

  1. Alcuni browser non consentono il collegamento delle app. Ad esempio, puoi configurare http://example.com in modo che venga catturato nell’app, ma se questo link viene cliccato dall’utente tramite l’app di Facebook, questo non viene gestito e il browser di Facebook mostra il sito web.
  2. Non esiste una soluzione standard unica per gestire i collegamenti sia per le app Android che IOS.
  3. Nessuna soluzione pratica se l’app non è installata sul dispositivo mobile e l’utente fa clic su un collegamento app.

Ho scritto questo Q & A che è il risultato dei miei studi (trascorsi troppe ore) per avere una soluzione unica e funzionante per tutti i casi.

I codici provengono dalla mia soluzione di lavoro, ma ho rimosso alcune parti solo per mostrare l’idea. Se ci sono dei problemi di compilazione, si prega di seguire l’algoritmo e scrivere il proprio codice

Ecco la soluzione, vai passo dopo passo anche se conosci alcuni passaggi, perché ci sono trucchi nei codici. Inoltre alcune spiegazioni sono nelle righe di commento delle parti del codice, per favore leggile.

Gli esempi sono per gestire deeplink http://example.com/v/ dalle tue app Android e IOS con un argomento alla fine, ad esempio http://example.com/v/id-of-user?key=value.

1. Configurazione di Android

1.1 Aggiungi le informazioni sull’attività al tuo file AndroidManifest.xml:

              

1.2 Creare un’attività denominata appLinkHandlerActivity che gestirà i collegamenti su cui si fa clic

  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 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. Configurazione di IOS

Questo è più complesso di Android, spiegherò qui i punti necessari. Si prega di fare riferimento ai documenti: 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 Devi abilitare i domini associati durante la creazione di un ID app sul portale per sviluppatori Apple. Problema importante: è necessario disporre di un account sviluppatore Apple acquistato per abilitare questa opzione, ovvero senza acquistare un account sviluppatore, non è ansible provare AppLinks sul progetto IOS.

2.2 Nel progetto XCode, aprire la scheda “Capabilites” e triggersre i domini associati su On. Se non hai abilitato i domini associati nella sezione ID app del portale Apple Developer, questo potrebbe non essere selezionabile Aggiungi un entitlement facendo clic sul pulsante + sotto l’opzione Domains associati, scrivi “applinks: example.com”.

2.3 Crea un file sul tuo server web chiamato “apple-app-site-association” e questo file deve essere accessibile tramite https://example.com/apple-app-site-association HTTPS è obbligatorio e se non è valido Il collegamento app certificato SSL potrebbe non funzionare. Aggiungi le seguenti righe nel file dell’associazione sito Apple-app:

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

appID è il formato di {“ID team”. “ID bundle della tua app”}. Puoi trovare il tuo teamID nella sezione Dettagli dell’appartenenza al Portale per gli sviluppatori.

Gestiamo il link http://example.com/v/parameters, ma qui vedi che c’è un’altra configurazione di percorso per “/ ios / *”. È necessario per bypassare i browser non supportati, spiegherò più avanti.

2.4 Nel file AppDelegate.m aggiungi due metodi per gestire i clic dell’utente su 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 *[email protected]""; NSString *[email protected]""; NSString *handledUrlStr=[handledUrl parameterString]; NSString *handledUrlQueryPart; NSArray *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. Gestione dei clic non registrati.

3.1 Ok, le tue app Android e IOS dovrebbero gestire i clic sul link http://example.com/v/blabla e passare il parametro “blabla” alla variabile pCode utilizzata nei metodi che ho mostrato. Ma alcuni browser come l’app di Facebook potrebbero disabilitare i collegamenti delle app per funzionare. In questo caso, l’utente fa clic sul server Web e il browser tenta di mostrare il contenuto di http://example.com/v/blabla, che è probabilmente 404 Imansible trovare nella pagina. Per gestire questi clic configureremo il server Web Apache e reindirizzeremo gli utenti alla tua app. Se si utilizza IIS o un altro, non so come farlo, ma si può prendere questo esempio e utilizzare lo stesso algortihm per configurare il server web.

3.2 Scrivi le righe sottostanti nel file .htaccess nella directory principale di example.com

 #redirect to deeplink  #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]  

4. Reindirizzare gli utenti alle app

4.1 Le regole di reindirizzamento nel file .htaccess mostrate al punto 3 reindirizzano gli utenti al file deeplink.php. Quindi, ecco il contenuto di quel file per redirect gli utenti alla tua app.

  <?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=""; //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=""; } 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=""; } ?>            

5. Mostra agli utenti IOS un link per fare clic

5.1 Ecco il contenuto del file http://deep.example.com/deeplink-ios.php. Gli utenti vedranno una pagina come sotto, quando hanno cliccato sul link, quella richiesta dovrebbe essere gestita dalla tua app 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=""; ?>                

6. Analisi del caso:

6.1 Android

6.1.1 Case-1: l’app è installata sul dispositivo
• Richieste browser per http://example.com/v/blabla
• Android acquisisce il collegamento e crea l’attività configurata nel file manifest

6.1.2 Case-2: l’app è installata sul dispositivo
• Richieste browser per http://example.com/v/blabla
• Android non può intercettare il collegamento.
• Il browser si collega al web server, richiesta per / v / blabla
• Viene reindirizzato a deeplink.php? / V / blabla a causa della configurazione nel file .htaccess
• deeplink.php impara che è Android e reindirizza a: intent: // share / v / blabla / # Intent; scheme = myapp; S.browser_fallback_url = http% 3A% 2F% 2Fexample.com% 2Fget-app% 2F; package = com.example.app
• Android rileva la richiesta che è intenzionale: //, quindi a causa della configurazione nel file manifest myapp: // share / v / blabla viene gestito dall’attività

6.1.3 Case-3: l’app non è installata
• Richieste browser per http://example.com/v/blabla
• Android non può intercettare il collegamento.
• Il browser si collega al web server, richiesta per / v / blabla
• Viene reindirizzato a deeplink.php? / V / blabla a causa della configurazione nel file .htaccess
• deeplink.php impara che è Android e reindirizza a: intent: // share / v / blabla / # Intent; scheme = myapp; S.browser_fallback_url = http% 3A% 2F% 2Fexample.com% 2Fget-app% 2F; package = com.example.app
• Android rileva la richiesta che è per intent: //, ma non è stata installata un’app per id: com.example.app. In alcuni casi, restituisce e reindirizza il browser a http://example.com/get-app o alla pagina di installazione di Play Store della tua app

6.2 IOS

6.2.1 Case-1: l’app è installata sul dispositivo
• Richieste browser per http://example.com/v/blabla
• IOS cattura il collegamento e chiama il metodo continueUserActivity in AppDelegate.m

6.2.2 Case-2: l’app è installata sul dispositivo
• Richieste browser per http://example.com/v/blabla
• IOS non può intercettare il collegamento.
• Il browser si collega al web server, richiesta per / v / blabla
• Viene reindirizzato a deeplink.php? / V / blabla a causa della configurazione nel file .htaccess
• deeplink.php impara che è IOS e reindirizza a: http://deep.example.com/deeplink-ios.php?/v/blabla
• Il file deeplink-ios.php mostra un URL per l’utente. L’URL è: http://lify.me/ios/v/blabla
• L’utente fa clic sull’URL e le richieste del browser per http://lify.me/ios/v/blabla
• IOS intercetta la richiesta a causa della configurazione del percorso “/ ios / *” nel file di associazione sito Apple-App e chiama il metodo continueUserActivity in AppDelegate.m
• Se IOS non può intercettare la richiesta di http://lify.me/ios/v/blabla per qualsiasi motivo, si comporterà perché l’app non è installata sul dispositivo. Vedi quel caso.

6.2.3 Case-2: l’app non è installata sul dispositivo
• Richieste browser per http://example.com/v/blabla
• IOS non può intercettare il collegamento.
• Il browser si collega al web server, richiesta per / v / blabla
• Viene reindirizzato a deeplink.php? / V / blabla a causa della configurazione nel file .htaccess
• deeplink.php impara che è IOS e reindirizza a: http://deep.example.com/deeplink-ios.php?/v/blabla
• Il file deeplink-ios.php mostra un URL per l’utente. L’URL è: http://lify.me/ios/v/blabla
• L’utente fa clic sull’URL e le richieste del browser per http://lify.me/ios/v/blabla
• Se IOS non può intercettare la richiesta per http://lify.me/ios/v/blabla
• Il browser si collega al web server, richiede / ios / v / blabla
• Viene reindirizzato su http://itunes.apple.com/install-of-your-app a causa della configurazione nel file .htaccess sul server web

6.3 App Link viene cliccato su dispositivi non Android o IOS
• Richieste browser per http://example.com/v/blabla
• Il sistema operativo del dispositivo non può intercettare il collegamento.
• Il browser si collega al web server, richiesta per / v / blabla
• Viene reindirizzato a deeplink.php? / V / blabla a causa della configurazione nel file .htaccess
• deeplink.php impara che non è né IOS né Android, e reindirizza a: http://example.com/non-mobile