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 Application 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
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:
- 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.
- En cada proyecto de cada plataforma, creamos la implementación de la interfaz.
- Utilizamos una etiqueta de registro en la implementación de la interfaz en cada plataforma para facilitar al servicio de dependencia la resolución.
- 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:
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:
Añadiendo el número de teléfono y pulsando sobre el botón:
Podéis descargar el ejemplo completo realizado a continuación:
También tenéis el código fuente disponible e GitHub:
Recordar que podéis dejar en los comentarios cualquier tipo de sugerencia o pregunta.