Xamarin y otras especias | Charla

Saludos mi buen amigo¬†Cristopher Junior Vivieca Ramos¬†de ¬†viviecar.com¬†me invito a dar una charla en el Instituto Polit√©cnico Padre Segri en Santiago, Rep. Dominicana. donde estuve hablando sobre “Xamarin y otras especias”

Fotos del evento.

Presentación del evento.

Te gustaria que sea ponente en alguna charla ?

Si te gustaria que diera una charla sobre el mismo tema o otras tecnologías Microsoft no dudes en ponerte en contacto conmigo.

Bug DisplayAlert Xamarin.Forms

Solución para Bug DisplayAlert Xamarin.Forms

Disclaimer: Si alguno considera que no es un bug y es mas una mala pr√°ctica por parte de algunos developers dejo aca el link del bug aca.

Bug

Este sucede cuando implementamos DisplayAlert  en Xamarin.Forms  se traduce en dos ventanas emergentes, lo que obviamente no se espera, y este es el bug.

Estoy hablando de este bloque de código:

var resp = await DisplayAlert("","Seguro quieres salir?","Si", "No");
if (resp)
{ 
   //Hacer algo
}

Solucion

Lo que debemos hacer es  invocar el Display Alert  en el hilo de interfaz de usuario principal usando Xamarin.Forms.Device.BeginInvokeOnMainThread. Tenemos que pasar la acción que  ejecutará el DisplayAlert al hilo principal de la UI:

Device.BeginInvokeOnMainThread(new Action(async () =>
  {
       if(await DisplayAlert("", "Seguro quieres salir?", "Si", "No"))
       {
         //Hacer algo
       }
  }));

Que hace la solución?

Esto soluciona el problema, porque ahora estamos invocando el hilo principal de la interfaz de usuario. Nuestra DisplayAlert ahora se ejecuta solo una vez. Así que, sí, por ahora, podemos utilizar esta solución.

Sin embargo, es de esperar, que corrijan el error, por lo que sólo pueden ejecutar sin el método BeginInvokeOnMainThread. Espero que esto les puede ayudar con su desarrollos.

Si tienen algo que a√Īadir, dudas comentarios no duden en escribirme.

Documentacion: https://developer.xamarin.com/api/member/Xamarin.Forms.Device.BeginInvokeOnMainThread/p/System.Action

Aplicaciones bonitas con Xamarin Forms | Pt. 1

Aplicaciones bonitas con Xamarin Forms

Hace algunos días un developer me escribió y me contaba que Xamarin forms era asombroso que para el las aplicaciones era algo feas en cuanto a la UI, yo le respondí y le dije que si se puede solo que se necesita un poquito más de esfuerzo. Pues en la play store o en cualquiera de las tiendas se engancha mucho mas rápido al futuro usuario de nuestra app si tiene una interfaz atractiva y amigable.

Que necesito para comenzar ?

1) Visual Studio 2015 Community (gratis  o una version superior ) o Visual Studio for MAC.

Vamos a hablar de interfaces bonitas

 

XFParallax by DevsDNA

Super pero que es XFParallax by DevsDNA, pues XFParallax by DevsDNA busca implementar el muy popular efecto efecto Parallax muy famoso en la plataforma ios.

Pero Yhorby que te digo que quiero hacer apps bonitas en Xamarin Forms, calma colega que se puede implementar en Xamarin forms.

Como lo hago?

Pues puedes encontrar un proyecto de ejemplo en su repositorio de Github aquí. 

Con esta librer√≠a podemos crear el efecto¬†parallax en las tres plataformas : Android, iOS and Windows ‚Äď con ¬†Xamarin Forms

Pasamos a explicar como funciona la librería.

1. Primero debemos crear ¬†el codigo responsable para crear¬†¬†la vista efecto parallax . Creamos un¬†nuevo ‚ÄúContentView‚ÄĚ llamado ‚ÄúParallaxView‚ÄĚ:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DevsDNA.XFParallax.ParallaxView">
  <ContentView.Content>
    <Grid>
      <ContentView x:Name="Header" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Blue"/>
      <ScrollView x:Name="ParentScroll" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <ContentView x:Name="Body"/>
      </ScrollView>
    </Grid>
  </ContentView.Content>
</ContentView>

2. EL Code behind para ‚ÄúParallaxView.xaml.cs‚ÄĚ deberia lucir como este :

namespace DevsDNA.XFParallax
{
    using Xamarin.Forms;
 
    public partial class ParallaxView : ContentView
    {
        private double lastScroll = 0;
 
        public static readonly BindableProperty HeaderContentProperty = BindableProperty.Create(nameof(HeaderContent), typeof(ContentView), typeof(ParallaxView), coerceValue: HeaderContentCoerceValue);
        public static readonly BindableProperty HeaderScrollSpeedProperty = BindableProperty.Create(nameof(HeaderScrollSpeed), typeof(int), typeof(ParallaxView), 2);
        public static readonly BindableProperty BodyContentProperty = BindableProperty.Create(nameof(BodyContent), typeof(ContentView), typeof(ParallaxView), coerceValue: BodyContentCoerceValue);
        public static readonly BindableProperty BodyMarginProperty = BindableProperty.Create(nameof(BodyMargin), typeof(Thickness), typeof(ParallaxView), new Thickness(0), coerceValue: BodyMarginCoerceValue);
 
        public ParallaxView()
        {
            InitializeComponent();
            ParentScroll.Scrolled += ParentScroll_Scrolled;
        }
 
        public ContentView HeaderContent
        {
            get { return (ContentView)GetValue(HeaderContentProperty); }
            set { SetValue(HeaderContentProperty, value); }
        }
 
        public int HeaderScrollSpeed
        {
            get { return (int)GetValue(HeaderScrollSpeedProperty); }
            set { SetValue(HeaderScrollSpeedProperty, value); }
        }
 
        public ContentView BodyContent
        {
            get { return (ContentView)GetValue(BodyContentProperty); }
            set { SetValue(BodyContentProperty, value); }
        }
 
        public Thickness BodyMargin
        {
            get { return (Thickness)GetValue(BodyMarginProperty); }
            set { SetValue(BodyMarginProperty, value); }
        }
        /// 
        <summary>
        /// Important to call this method from Page OnDissapearing to remove event handlers and avoid memory leaks.
        /// </summary>
 
        public void DestroyParallaxView()
        {
            ParentScroll.Scrolled -= ParentScroll_Scrolled;
        }
 
        private static object HeaderContentCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is ContentView)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                instance.Header.Content = (ContentView)value;
            }
            return value;
        }
 
        private static object BodyContentCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is ContentView)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                instance.Body.Content = (ContentView)value;
 
                if (instance.BodyMargin != null)
                {
                    instance.Body.Margin = instance.BodyMargin;
                }
            }
            return value;
        }
 
        private static object BodyMarginCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is Thickness)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                if (instance.Body != null)
                {
                    instance.Body.Margin = instance.BodyMargin;
                }
            }
            return value;
        }
 
        private void ParentScroll_Scrolled(object sender, ScrolledEventArgs e)
        {
            if (lastScroll == 0)
                lastScroll = e.ScrollY;
            else
            {
                CalculateHeaderTranslation(e);
            }
        }
 
        private void CalculateHeaderTranslation(ScrolledEventArgs e)
        {
            double translation = 0;
 
            if (lastScroll < e.ScrollY) { translation = 0 - ((e.ScrollY / HeaderScrollSpeed)); if (translation > 0)
                    translation = 0;
            }
            else
            {
                translation = 0 + ((e.ScrollY / HeaderScrollSpeed));
                if (translation > 0)
                    translation = 0;
            }
            Header.TranslateTo(Header.TranslationX, translation);
            lastScroll = e.ScrollY;
        }
    }
}

3. Ahora podemos usar Parallax en una de nuestras  Content Pages, como se muestra a  continuación:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:DevsDNA.XFParallax.Sample" xmlns:parallax="clr-namespace:DevsDNA.XFParallax;assembly=DevsDNA.XFParallax" x:Class="DevsDNA.XFParallax.Sample.MainPage">
 
  <parallax:ParallaxView x:Name="MainParallax" BodyMargin="0,180,0,0" HeaderScrollSpeed="4">
    <parallax:ParallaxView.HeaderContent>
      <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Blue">
        <Image Source="https://www.windowscentral.com/sites/wpcentral.com/files/styles/large/public/field/image/2016/02/microsoft-xamirin.jpg?itok=M_JRL3qE" Aspect="AspectFill" VerticalOptions="Start"/>
      </ContentView>
    </parallax:ParallaxView.HeaderContent> 
    <parallax:ParallaxView.BodyContent>
      <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="White" HeightRequest="500">
        <ContentView.Margin>
          <!-- need to add specific margin to Windows to show header.-->
          <OnPlatform x:TypeArguments="Thickness" WinPhone="0,180,0,0"/>
        </ContentView.Margin>
        <Grid BackgroundColor="White">
                    <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
                </Grid.RowDefinitions>
                     
                <Image HorizontalOptions="Center" VerticalOptions="Start" Margin="0,-50,0,0" HeightRequest="100" WidthRequest="100" Grid.Row="0" Source="http://students.stmaryschs.org.uk/Y9_Scratch_To_VB/images/VS_Logo.png" Aspect="AspectFit"/>
                <Label Text="Xamarin Parallax Effect!" Grid.Row="1" HorizontalOptions="Center"/>
                     
        </Grid>
      </ContentView>
    </parallax:ParallaxView.BodyContent>
  </parallax:ParallaxView>
 
</ContentPage>

4. Ahora en el ¬†code behind invocamos¬†‚ÄúDestroyParallaxView‚ÄĚ en el m√©todo llamado ¬†MainParallax¬†en el metodo ‚ÄúOnDisappearing‚ÄĚ :

public partial class MainPage : ContentPage
  {
      public MainPage()
      {
          InitializeComponent();
      }
 
      protected override void OnDisappearing()
      {
          base.OnDisappearing();
          // To avoid memory leak:
          MainParallax.DestroyParallaxView();
      }
  }

Y así es como tenemos el hermoso efecto Parrallax en nuestra aplicacion Xamarin Forms.

Quieres verlo funcionando ?

Ejecuta tu codigo y dejame saber que tal !!

Cualquier duda o comentario puedes escribirme o dejar un comentario en la entrada !

Xamarin Diplomado Latinoamérica 3.0

Xamarin Diplomado Latinoamérica 3.0

Microsoft México se anunció una nueva versión del #XamarinDiplomado: Xamarin Diplomado Latinoamérica 3.0, el cual abarcará desde los temas básicos (instalación de herramientas) hasta temas más avanzados, con nuevos speakers y sorpresas.

De momento no se ha dado m√°s informaci√≥n sobre la fecha de inicio y los temas espec√≠ficos del diplomado, pero ya te puedes registrar, dando clic en el siguiente enlace: —>¬†diplomadoxamarin

Xamarin Diplomado es gratis !

Recuerda que el diplomado es gratuito y que aprender√°s muchas cosas nuevas sobre Xamarin, una herramienta que te permite desarrollar aplicaciones m√≥viles multiplataforma que se pueden ejecutar en Android, iOS y Windows 10. Si ya tomaste los diplomados anteriores, contin√ļa con tu formaci√≥n en esta nueva versi√≥n del curso; y si no has comenzado con Xamarin pero te interesa aprender, pues esta es una excelente oportunidad para hacerlo, dado que el curso comenzar√° desde lo b√°sico. Y en espa√Īol.

Crash Analytics en Xamarin Forms

Saludos en esta entrada tratar√© un tema muy interesante e importante para una aplicaci√≥n, vamos a ver c√≥mo obtener la anal√≠tica de Crash (cuando nuestra app explota)¬†de la aplicaci√≥n de Xamarin Froms. Crash Analytics nos permite realizar un seguimiento de las excepciones, eventos y el comportamiento de la aplicaci√≥n, puede ser Android o iOS., est√° dise√Īada para rastrear a los usuarios, los eventos y los veces que nuestra aplicacion se detiene, an√°lisis de incidentes¬†capturar√° todos los datos de su aplicaci√≥n y autom√°ticamente se sincronizar√° con el servidor y en ¬†tiempo real ¬†se reflejar√° en el portal respectivo de Crash Analytics que estemos usando. Herramientas como las de Google Analytics¬†nos ayudar√°n a comprender que la gente est√° utilizando nuestra aplicaci√≥n, cu√°l es el punto de error y c√≥mo podemos mejorar nuestra aplicaci√≥n.

Hay diferentes tipos de herramientas de Analytics están disponibles en el mercado, cada uno de ellas tiene diferentes capacidades para capturar análisis, algunas de estas  son pagas  y algunas de libre también. A continuación se muestra la lista de varias herramientas de análisis,

  1. Google Analytics
  2. Flurry Analytics
  3. Mix Panel

Crash Analytics con Flurry

A continuación  voy a explicar detalladamente sobre el análisis de Flurry que está disponible gratis y fácil de usar, sino que también proporciona los datos efectivos para fines de análisis, algunas de las ventajas de la Flurry Analytics son los siguientes,

  • Seguimiento de la sesi√≥n
  • Registro de eventos, con par√°metros opcionales
  • Seguimiento de la vista de p√°gina
  • Seguimiento de datos demogr√°ficos, como edad, sexo e identificador de usuario
  • Seguimiento de ubicaci√≥n
  • Seguimiento de la versi√≥n de la aplicaci√≥n, etc …

Aqui estan los pasos para agregar las analiticas de flurry a una aplicacion hecha en Xamarin Forms

  • 1. En primer lugar, tendr√°s que crear una cuenta en Flurry (es gratis) para crear una cuenta. Visita https://login.flurry.com/signup, completa todos los pasos de registro y accede al portal de Flurry.
  • 2. Despu√©s de iniciar sesi√≥n Elija la plataforma en la que desea obtener los an√°lisis, como Android / iOS, etc.
  • 3. Ahora vamos a la pesta√Īa Aplicaciones y agregamos la aplicaci√≥n, A√Īadir nombre y la categor√≠a de la aplicaci√≥n, luego saltar√° a la pantalla Aplicaci√≥n donde puede ver la clave de la aplicaci√≥n que es una clave √ļnica y se utiliza para identificar su aplicaci√≥n.

Para cada SDK vamos necesitar un key diferente, ahora mediante el nuget package agregamos el paquete Flurry Analitycs

Hecho esto podemos agregar ya el siguiente codigo para empezar a analizar nuestra aplicación, como en el portal de flurry dijimos que la app era Android , debemos tener en cuenta que vamos a poner el siguiente codigo en el MainActivity.cs  de nuestro proyecto android.

El código es el siguiente:

 FlurryAgent.Init(Xamarin.Forms.Forms.Context, "Your_App_Key");             
FlurryAgent.OnStartSession(Xamarin.Forms.Forms.Context);                                  
FlurryAgent.SetLogEnabled(true);                                         
FlurryAgent.SetLogEvents(true);

Ya que hemos hecho la configuración para la plataforma android, podemos empezar a registrar errores, eveno y excepciones.

Para errores:

 AnalyticsApi.LogError("My Exception", ex); 

Para eventos:

   AnalyticsApi.LogEvent("My Event"); 

Para bindaer datos en los eventos

AnalyticsApi.LogEvent("My Event"+data);    

 

Podemos registrar Eventos y Excepciones en cualquier parte del código,

  • Views: login.xaml.cs
  • ViewModel
  • Repositorio (llamadas API)

Así que ahora  terminado con el registro de la excepción y los eventos de la aplicación,  para ver el análisis que tenemos, debemos iniciar sesión en el portal de Flurry, y seleccionar la aplicación que hemos creado, en el tablero de aplicaciones se pueden ver varias opciones de informes y métricas.

Crash Analytics en cualquier tecnología móvil ayudará a la organización / desarrolladores a aprender dónde se utiliza la aplicación ampliamente y donde los usuarios se enfrentan a problemas, esta servira de  auxilio para entender cómo se comporta la aplicación cuando se utiliza por el cliente y  el análisis proporcionará los datos que hacen que una aplicación sea más optimizada y libre de errores.

Si tienes alguna duda o alg√ļn comentario, h√°zmelo saber deja un comentario ac√° o escribeme a Twitter @yhorbymatias

Portable Class Library (PCL) vs Shared Projects en Xamarin Forms

Si navegamos por la web buscando ejemplos de proyectos o tutoriales de  Xamarin Forms , nos encontraremos  muchos ejemplos usando Shared Projects, por esta razón la mayoría de los recién  iniciados a Xamarin basan sus primeras aplicaciones en estos ejemplos.

Además de los casos de uso heredados, hay razones muy limitadas para usar SharedProjects en aplicaciones Xamarin Forms, las PCL son el método preferido en la mayoría de los escenarios.

En una oportunidad participe en un webinar dictado por el MVP Humberto Jaimes donde toco este tópico, tratare de explicar en este post  lo aprendido y el  research que hice a parte para documentarme.

Shared code

Este al momento de compilar incorpora en cada assembly una¬†referencia al proyecto compartido. Esto puede ser √ļtil cuando deseamos crear assembly por ¬†separados que se orientan a plataformas espec√≠ficas, pero todav√≠a el¬†c√≥digo debe ser compartido.

 

Portable Class Library (PCL)

Los proyectos apuntan a perfiles específicos que soportan un conjunto conocido de clases / características BCL. Sin embargo, el lado negativo de PCL es que a menudo requieren esfuerzo arquitectónico adicional para separar el código específico del perfil en sus propias bibliotecas.

Aplicando al mundo real

Con  SharedProject podemos crear las clases como de costumbre, pero si queremos hacer algo específico de la plataforma que estemos trabajando, tenemos que implementar una directiva de compilación en nuestro código.

Por ejemplo.

public string GetTargetPlatform()
{

  var path = "unknown";
  
  #if WINDOWS_PHONE
  path = "windowsphone";
  #else
  
  #if __SILVERLIGHT__
  path = "silverlight";
  #else
  
  #if __ANDROID__
  path = "android";
  #else
  
  #if __IOS__
  path = "iOS";
  #else
  
  
  return path;
}

Estas clases parciales pueden ser buenas para peque√Īos proyectos o demos. ¬†Sin embargo, si la App tiene varios desarrolladores trabajando en ella ¬†o es ¬†algo m√°s que una aplicaci√≥n realmente simple o proyecto de demostraci√≥n, la capacidad de mantenimiento de un proyecto compartido se vuelve menos agradable debido a la falta de control arquitect√≥nico y vamos a estar ¬†luchando por encontrar lo que realmente se est√° ejecutando en cada plataforma.

Un problema de los shared, es que en un proyecto compartido tiene problemas al definir un nombre de ensamblado. Por ejemplo, en xaml si desea hacer referencia a un control y hacer referencia a un nombre de assembly, cada proyecto nativo tendrá un nombre de assembly distinto, por lo que deberá realizar más ifdefs o OnPlatforms, o nombrar cada proyecto nativo con el mismo nombre de assembly.

las PCLs

No crean que las¬†PCLs no vienen con¬†sus propios ¬†dolores de cabeza pero, proporcionan una asombrosa manera de escribir c√≥digo f√°cil¬† de mantener y probarlo ¬†una vez que la aprendemos a utilizar en m√ļltiples plataformas. Cuando se escribe una PCL, no es necesario insertar directivas de compilaci√≥n ¬†para cambiar el c√≥digo en funci√≥n de cada plataforma, se seleccionan las plataformas que se van a admitir y luego se inicia a escribir el c√≥digo de nuestra APP. Cuando creamos un PCL, luego podemos ir a Propiedades y establecer los Targets para el proyecto.

targetprofile

PCL son proyectos que pueden dirigirse a diferentes plataformas, podemos elegir cu√°les y luego esta nos da acceso a ciertos conjuntos y funciones, dependiendo de cu√°les seleccionemos. Las diferentes combinaciones de objetivos para PCL se denominan perfiles y cada perfil tiene su propio n√ļmero. El perfil m√°s com√ļn y recomendado para los proyectos Xamarin Forms es Profile259.

Beneficios

Algunos beneficios del uso de PCL son:
Pruebas de unit testing mas sencillas de aplicar
Código mas facil de leer
Mayor portabilidad
Mejor implementacion  del código

Cual usar ?

Yo en lo personal para grandes proyectos de arquitecturas complejas y una gran necesidad de c√≥digo portable recomiendo las PCL, en cambio para proyectos peque√Īos, prototipos y demos recomiendo usar Shared Projects.

 

Si no estas de acuerdo en algo o tienes algo que agregar d√©jalo en los comentarios ! ūüôā

 

 

Xamarin.Forms Splashscreen para Android

No es secreto que el inicio de toda aplicación es un Splashscreen ya sea para mostrar el branding o verificar recursos.

Para agregar un Splashscreen en Xamarin Forms a la parte Android yo lo hago de la siguiente forma:

En la parte de la Solución que pertenece a Android vamos y agregamos un nuevo Activity yo siempre le llamo Splashscreen, el código que contendrá es el siguiente :

[Activity(Label = "Splashscreen", MainLauncher = true, NoHistory = true, Theme = "@style/Theme.Splash", 
    ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class SplashScreen : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        var intent = new Intent(this, typeof(MainActivity));
        StartActivity(intent);
      
    }
}

Un poco de explicacion:

 MainLauncher = true 

nos indica que este es el activity que se ejecutara primero.

NoHistory = true

evita que presionando la tecla atr√°s, se vuelva al Splash

 

El código de nuestro MainActivity.cs sera el siguiente:

[Activity(Label = "Splashscreen", Theme="@android:style/Theme.Holo", 
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : AndroidActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        Xamarin.Forms.Forms.Init(this, bundle);
        SetPage(App.GetMainPage());
    }
}

Ahora en el Resources.Drawable.SplashScreen.xml: 

<?xml version="1.0" encoding="utf-8" ?> 
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
   android:src="@drawable/splash_logo"
  android:gravity="center"
  android:layout_gravity="center"/>

Que es donde definimos los elementos gr√°ficos de nuestro splash

Ahora vamos con el Resources.Values.Styles.xml:

 

<resources>
  <style name="Theme.Splash"
    parent="android:Theme">
    <item name="android:windowBackground">
      @drawable/splashscreen
    </item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsTranslucent">false</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:backgroundDimEnabled">true</item>
  </style>
</resources>

 

Ahora el ejecutar nuestra aplicación el resultado sera similar a este :

splashscreen1

Alguna duda, comentario, error o sugerencia no dudes en escribirme.