[Xamarin.Forms] Utilizando DependencyService

Razones para extender Xamarin.Forms

Xamarin.Forms es un toolkit que crea una abstracción sobre la interfaz de usuario de Android, iOS y Windows Phone permitiendo desarrollarla una única vez con código C# o Extensible DependencyService 02Application Markup Language (XAML).
Permite crear facilmente y con rapidez interfaces de usuario nativas
compartidas donde  cada elemento visual en Xamarin.Forms son mapeados a
elementos nativos y comportamientos propios de cada plataforma.

Sin embargo, esta posibilidad a veces supone grandes dudas, ¿podemos extender Xamarin.Forms en caso necesario?

Las necesidades principales para extender Xamarin.Forms son:

  • Modificar aspectos de la UI.
  • Aprovechar a fondo las capacidades que nos ofrece cada plataforma.
  • Cubrir ciertas necesidades creando nuevos controles o páginas.

Xamarin.Forms incluye un servicio de dependencia, DependencyService
que nos permite compartir interfaces de usuario y resolver con
facilidad la implementación de la misma en cada plataforma específica.
De esta forma podremos acceder a APIs específicas de cada plataforma
desde nuestra PCL o proyecto Shared.

En este artículo vamos a profundizar en el servicio de dependencia de Xamarin.Forms asi como su uso.

DependencyService

El servicio de dependencia nos permite acceder a funcionalidad nativa
de cada plataforma resolviendo la implementación de una sencilla
interfaz. El esquema general de uso del servicio de dependencia sería el
siguiente:

DependencyService

DependencyService

En el diagrama de la parte superior se detalla de forma visual los
pasos necesarios para poder realizar llamadas telefónicas desde la App.
Los pasos detallados serían:

  1. Creamos una interfaz común y compartida donde
    definimos la funcionalidad a cubrir en la implementación de cada
    plataforma. Esta interfaz estara definida dentro de nuestra PCL o
    proyecto Shared.
  2. En cada proyecto de cada plataforma, creamos la implementación de la interfaz.
  3. Utilizamos una etiqueta de registro en la implementación de la interfaz en cada plataforma para facilitar al servicio de dependencia la resolución.
  4. En nuestro código compartido (normalmente desde ViewModels) utilizaremos DependencyService.Get<> para obtener la implementación de la interfaz indicada específica de la plataforma en ejecución.

Utilizando DependencyService

Para analizar el uso del servicio de dependencia vamos a crear un nuevo proyecto desde cero:

Nueva App Xamarin.Forms

Nueva App Xamarin.Forms

Nuestro objetivo sera crear una App Xamarin.Forms destinada a iOS,
Android y Windows Phone que nos permita realizar llamadas por teléfono.

1. Creando la definición del Servicio

Comenzamos creando una carpeta Services en nuestro proyecto PCL. Dentro de esta carpeta creamos una interfaz:

public interface ICallService
{
     void MakeCall(string phone);
}

La interfaz nos definirá la implementación que será necesaria en cada
plataforma. En nuestro caso, un sencillo método al que le pasamos el
número de teléfono y nos permite realizar la llamada (MakeCall).

2. Implementando la interfaz en cada plataforma

El siguiente paso consistirá en realizar la implementación de la interfaz en cada proyecto nativo.

La implementación en Windows Phone:

class CallService : ICallService
{
     public static void Init() { }
 
     public void MakeCall(string phone)
     {
          var phoneCallTask = new PhoneCallTask { PhoneNumber = phone };
 
          phoneCallTask.Show();
     }
}

NOTA: Las clases con implementación requieren de un contructor sin parámetros para que el servicio de dependencia pueda resolverla.

La implementación en Android:

public class CallService : ICallService
{
     public static void Init()
     {
 
     }
 
     public void MakeCall(string phone)
     {
         if (System.Text.RegularExpressions.Regex.IsMatch(phone, "^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$"))
         {
             var uri = Android.Net.Uri.Parse(String.Format("tel:{0}", phone));
             var intent = new Intent(Intent.ActionView, uri);
             Xamarin.Forms.Forms.Context.StartActivity(intent);
         }
         else
         {
             Debug.WriteLine("Invalid number!");
         }
     }
}

En iOS:

public class CallService : ICallService
{
     public static void Init() { }
 
     public void MakeCall(string phone)
     {
         if (System.Text.RegularExpressions.Regex.IsMatch(phone, "^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$"))
         {
             var url = new NSUrl(string.Format(@"telprompt://{0}", phone));
             UIApplication.SharedApplication.OpenUrl(url);
         }
         else
         {
             Debug.WriteLine("Invalid phone number!");
         }
     }
}

3. Registro de la implementación

Añadimos la etiqueta [assembly] encima de la clase, incluido la definición del namespace.

[assembly: Dependency(typeof(CallService))]

Este atributo registra la clase como implementación de la interfaz
ICallService. Esto permitirá acceder a la instancia de la implementación
desde código compartido utilizando DependencyService.Get<ICallService>().

4. Utilizar el servicio desde la PCL o proyecto Shared

Llegados a este punto lo tenemos todo listo, solo nos falta utilizar el servicio!.

ICallService callService = DependencyService.Get<ICallService>();
callService.MakeCall(“6123456789”);

Ejecutando la App:

Nuestra App!

Nuestra App!

Añadiendo el número de teléfono y pulsando sobre el botón:

Llamar por teléfono

Llamar por teléfono

Podéis descargar el ejemplo completo realizado a continuación:

También tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordar que podéis dejar en los comentarios cualquier tipo de sugerencia o pregunta.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *