Indexación de la aplicación y vinculación en profundidad
La indexación de la aplicación y la vinculación en profundidad de Xamarin.Forms proporcionan una API para la publicación de metadatos y la indexación de las aplicaciones a medida que los usuarios navegan por ellas. Posteriormente, el contenido indexado se puede buscar en una búsqueda web, de Spotlight o de Google. Al pulsar en un resultado de la búsqueda que contenga un vínculo profundo, se desencadenará un evento que normalmente se usa para navegar a la página a la que se hace referencia desde el vínculo profundo y que puede controlarse mediante una aplicación.
La aplicación de ejemplo muestra una aplicación de lista de tareas pendientes en la que los datos se almacenan en una base de datos SQLite local, tal como aparece en las siguientes capturas de pantalla:
Se indexan todas las instancias del elemento TodoItem
que crea el usuario. A continuación, se puede usar una búsqueda específica de la plataforma para localizar los datos indexados de la aplicación. Cuando el usuario pulsa un resultado de la búsqueda de la aplicación, esta se inicia, se navega al elemento TodoItemPage
y se muestra el elemento TodoItem
al que se hace referencia desde el vínculo profundo.
Para obtener más información sobre el uso de una base de datos SQLite, consulte Bases de datos locales de Xamarin.Forms.
Nota:
La función de indexación de la aplicación y vinculación en profundidad de Xamarin.Forms solo está disponible en las plataformas iOS y Android y necesita como mínimo iOS 9 y API 23, respectivamente.
Configuración
En las siguientes secciones se proporcionan las instrucciones de instalación adicionales para usar esta característica en las plataformas iOS y Android.
iOS
En la plataforma iOS, asegúrese de que el proyecto de plataforma de iOS establezca el archivo Entitlements.plist como de derechos personalizados para firmar el conjunto.
Para usar vínculos universales de iOS, realice lo siguiente:
- Agregue un derecho de dominios asociados a la aplicación con la clave
applinks
, incluidos todos los dominios que admitirá la aplicación. - Agregue un archivo de asociación de sitios de la aplicación de Apple a su sitio web.
- Agregue la clave
applinks
al archivo de asociación de sitios de la aplicación de Apple.
Para obtener más información, vea Allowing Apps and Websites to Link to Your Content (Permitir la vinculación de contenido a aplicaciones y sitios web) en developer.apple.com.
Android
En la plataforma Android, se deben cumplir los siguientes requisitos previos para usar la funcionalidad de la indexación de la aplicación y de la vinculación en profundidad:
- Es necesario tener una versión de la aplicación publicada en Google Play.
- Es necesario haber registrado un sitio web complementario para la aplicación en la consola del desarrollador de Google. Una vez que la aplicación esté asociada a un sitio web, las direcciones URL se pueden indexar de forma que funcionen tanto para el sitio web como para la aplicación. De este modo, podrán aparecer después en los resultados de la búsqueda. Para obtener más información, vea Indexar aplicaciones en la Búsqueda de Google en el sitio web de Google.
- La aplicación debe admitir las intenciones de dirección URL HTTP en la clase
MainActivity
, que indican a la indexación de la aplicación los tipos de esquemas de datos de direcciones URL a los que esta puede dar respuesta. Para obtener más información, vea Configuración del filtro de intención.
Una vez cumplidos estos requisitos previos, para usar la indexación de la aplicación y la vinculación en profundidad de Xamarin.Forms en la plataforma Android es necesaria la siguiente configuración adicional:
- Instale el paquete NuGet Xamarin.Forms.AppLinks en el proyecto de la aplicación de Android.
- En el archivo MainActivity.cs, agregue una declaración para usar el espacio de nombres
Xamarin.Forms.Platform.Android.AppLinks
. - En el archivo MainActivity.cs, agregue una declaración para usar el espacio de nombres
Firebase
. - En un explorador web, cree un nuevo proyecto con la consola Firebase.
- En la consola Firebase, agregue Firebase a la aplicación Android y escriba los datos necesarios.
- Descargue el archivo google-services.json resultante.
- Agregue el archivo google-services.json al directorio raíz del proyecto de Android y establezca el valor Acción de compilación en GoogleServicesJson.
- En la invalidación del elemento
MainActivity.OnCreate
, agregue la siguiente línea de código debajo deForms.Init(this, bundle)
:
FirebaseApp.InitializeApp(this);
AndroidAppLinks.Init(this);
Al agregar google-services.json al proyecto (y al establecer la acción de compilación GoogleServicesJson\*), el proceso de compilación extraerá la clave de API y el id. de cliente. A continuación, las credenciales se agregarán al archivo de manifiesto generado.
Nota:
En este artículo, los términos vínculos de aplicación y vínculos profundos suelen usarse indistintamente. Sin embargo, en Android estos términos tienen significados diferentes. En Android, un vínculo profundo es un filtro de intención que permite a los usuarios especificar directamente una actividad concreta en la aplicación. Al hacer clic en un vínculo profundo se puede abrir un cuadro de diálogo de desambiguación, que permite al usuario seleccionar una de las distintas aplicaciones que pueden controlar la dirección URL. Un vínculo de aplicación de Android es un vínculo profundo basado en la dirección URL de su sitio web, que se ha verificado que pertenece al sitio web. Al hacer clic en un vínculo de aplicación, se abre la aplicación si está instalada, sin que se abra un cuadro de diálogo de desambiguación.
Para obtener más información, vea Contenido de vínculos profundos con la navegación de direcciones URL de Xamarin.Forms en el blog de Xamarin.
Indexación de una página
El proceso de indexación de una página y de exposición en una búsqueda de Spotlight y Google es el que sigue:
- Cree un elemento
AppLinkEntry
que contenga los metadatos necesarios para indexar la página y un vínculo profundo para volver a ella cuando el usuario seleccione el contenido indexado en los resultados de la búsqueda. - Registre la instancia
AppLinkEntry
con el fin de indexarla para la búsqueda.
En el siguiente ejemplo de código se muestra cómo crear una instancia AppLinkEntry
:
AppLinkEntry GetAppLink(TodoItem item)
{
var pageType = GetType().ToString();
var pageLink = new AppLinkEntry
{
Title = item.Name,
Description = item.Notes,
AppLinkUri = new Uri($"http://{App.AppName}/{pageType}?id={item.ID}", UriKind.RelativeOrAbsolute),
IsLinkActive = true,
Thumbnail = ImageSource.FromFile("monkey.png")
};
pageLink.KeyValues.Add("contentType", "TodoItemPage");
pageLink.KeyValues.Add("appName", App.AppName);
pageLink.KeyValues.Add("companyName", "Xamarin");
return pageLink;
}
La instancia AppLinkEntry
contiene un número de propiedades cuyos valores son necesarios para indexar la página y crear un vínculo profundo. Las propiedades Title
, Description
y Thumbnail
se usan para identificar el contenido indexado cuando este aparece en los resultados de la búsqueda. La propiedad IsLinkActive
se establece en true
para indicar que se está visualizando el contenido indexado. La propiedad AppLinkUri
es un elemento Uri
que contiene la información necesaria para volver a la página actual y mostrar el elemento TodoItem
actual. A continuación encontrará un elemento Uri
de muestra para la aplicación de ejemplo:
http://deeplinking/DeepLinking.TodoItemPage?id=2
Este elemento Uri
contiene toda la información necesaria para iniciar la aplicación deeplinking
, navegar a DeepLinking.TodoItemPage
y mostrar TodoItem
, que tiene un valor ID
de 2.
Registro del contenido para la indexación
Una vez que la instancia AppLinkEntry
se ha creado, esta se debe registrar para la indexación con el fin de que aparezca en los resultados de la búsqueda. Esto se consigue con el método RegisterLink
, como se muestra en el ejemplo de código siguiente:
Application.Current.AppLinks.RegisterLink (appLink);
Esto agrega la instancia AppLinkEntry
a la colección AppLinks
de la aplicación.
Nota:
El método RegisterLink
también se puede utilizar para actualizar el contenido que se ha indexado para una página.
Una vez que la instancia AppLinkEntry
se ha registrado para la indexación, esta puede aparecer en los resultados de la búsqueda. La siguiente captura de pantalla muestra el contenido indexado que aparece en los resultados de la búsqueda en la plataforma iOS:
Anulación del registro del contenido indexado
El método DeregisterLink
se usa para eliminar el contenido indexado de los resultados de la búsqueda, tal como se muestra en el siguiente ejemplo de código:
Application.Current.AppLinks.DeregisterLink (appLink);
Esto elimina la instancia AppLinkEntry
de la colección AppLinks
de la aplicación.
Nota:
En Android no es posible eliminar contenido indexado de los resultados de la búsqueda.
Respuesta a un vínculo profundo
Cuando aparece contenido indexado en los resultados de la búsqueda y un usuario lo selecciona, la clase App
de la aplicación recibirá una solicitud para controlar el elemento Uri
incluido en dicho contenido indexado. Esta solicitud se puede procesar en la invalidación del elemento OnAppLinkRequestReceived
, tal como se muestra en el siguiente ejemplo de código:
public class App : Application
{
...
protected override async void OnAppLinkRequestReceived(Uri uri)
{
string appDomain = "http://" + App.AppName.ToLowerInvariant() + "/";
if (!uri.ToString().ToLowerInvariant().StartsWith(appDomain, StringComparison.Ordinal))
return;
string pageUrl = uri.ToString().Replace(appDomain, string.Empty).Trim();
var parts = pageUrl.Split('?');
string page = parts[0];
string pageParameter = parts[1].Replace("id=", string.Empty);
var formsPage = Activator.CreateInstance(Type.GetType(page));
var todoItemPage = formsPage as TodoItemPage;
if (todoItemPage != null)
{
var todoItem = await App.Database.GetItemAsync(int.Parse(pageParameter));
todoItemPage.BindingContext = todoItem;
await MainPage.Navigation.PushAsync(formsPage as Page);
}
base.OnAppLinkRequestReceived(uri);
}
}
El método OnAppLinkRequestReceived
comprueba que el elemento Uri
recibido esté dirigido a la aplicación, antes de analizar el elemento Uri
para la página a la que se navegará y el parámetro que se pasará a la página. Luego, se crea una instancia de la página a la que se navegará y se recupera el elemento TodoItem
representado por el parámetro de la página. Posteriormente, el elemento BindingContext
de la página a la que se navegará se establece en TodoItem
. Esto garantiza que, cuando el método PushAsync
muestre TodoItemPage
, se muestre también el elemento TodoItem
cuyo valor ID
se encuentra en el vínculo profundo.
Disponibilidad del contenido para la indexación de la búsqueda
Cada vez que se muestra la página representada por un vínculo profundo, la propiedad AppLinkEntry.IsLinkActive
se puede establecer en true
. En iOS y Android, esto hace que la instancia AppLinkEntry
esté disponible para la indexación de la búsqueda y, solo en iOS, también facilita la instancia AppLinkEntry
para Handoff. Para obtener más información sobre Handoff, vea la introducción a Handoff.
El siguiente ejemplo de código muestra cómo establecer la propiedad AppLinkEntry.IsLinkActive
en true
en la invalidación del elemento Page.OnAppearing
:
protected override void OnAppearing()
{
appLink = GetAppLink(BindingContext as TodoItem);
if (appLink != null)
{
appLink.IsLinkActive = true;
}
}
Asimismo, al salir de una página representada por un vínculo profundo, la propiedad AppLinkEntry.IsLinkActive
se puede establecer en false
. En iOS y Android, esto evita que la instancia AppLinkEntry
se anuncie en la indexación de la búsqueda y, solo en iOS, también evita anunciar la instancia AppLinkEntry
para Handoff. Esto se puede conseguir en la invalidación del elemento Page.OnDisappearing
, tal como se muestra en el siguiente ejemplo de código:
protected override void OnDisappearing()
{
if (appLink != null)
{
appLink.IsLinkActive = false;
}
}
Envío de datos a Handoff
En iOS, los datos específicos de la aplicación se pueden almacenar al realizar la indexación de la página. Para hacerlo, agregue datos a la colección KeyValues
, que es un elemento Dictionary<string, string>
para almacenar los pares clave-valor que se usan en Handoff. Handoff es una forma que tiene el usuario de iniciar una actividad en uno de sus dispositivos y continuar con ella en otro (de acuerdo con la identificación de la cuenta de iCloud del usuario). El siguiente código muestra un ejemplo de almacenamiento de pares clave-valor específicos de la aplicación:
var pageLink = new AppLinkEntry
{
...
};
pageLink.KeyValues.Add("appName", App.AppName);
pageLink.KeyValues.Add("companyName", "Xamarin");
Los valores almacenados en la colección KeyValues
se almacenarán en los metadatos de la página indexada y se restaurarán cuando el usuario pulse un resultado de la búsqueda que contenga un vínculo profundo, o bien al utilizar Handoff para ver el contenido en otro dispositivo en el que haya iniciado sesión.
Además, se pueden especificar valores para las siguientes claves:
contentType
:string
que especifica el identificador de tipo uniforme del contenido indexado. La convención que se recomienda usar para este valor es el nombre del tipo de la página que contiene el contenido indexado.associatedWebPage
:string
que representa la página web que se va a visitar si el contenido indexado también se puede ver en la Web, o bien si la aplicación admite vínculos profundos de Safari.shouldAddToPublicIndex
:string
detrue
ofalse
que controla si se debe agregar el contenido indexado al índice de la nube pública de Apple y que, posteriormente, se puede presentar a los usuarios que no hayan instalado la aplicación en su dispositivo iOS. Sin embargo, el hecho de que el contenido se haya establecido para la indexación pública no significa que se agregue automáticamente al índice de la nube pública de Apple. Para obtener más información, vea Indexación de búsqueda pública. Tenga en cuenta que, al agregar datos personales a la colecciónKeyValues
, esta clave se debe establecer enfalse
.
Nota:
La colección KeyValues
no se usa en la plataforma Android.
Para obtener más información sobre Handoff, vea la introducción a Handoff.