[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

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s