Ir al contenido principal

Xamarin.Forms - Login con SQLite

En este post elaboraremos un ejemplo práctico para el inicio de sesión, con el fin de controlar los accesos de usuarios a las diferentes opciones de nuestra aplicación móvil.

De paso les dejo el link (App - DÍAbetes) donde se viene detallando todo lo elaborado acerca del diseño y desarrollo de la aplicación.

El ejemplo práctico será diseñada y desarrollada en Xamarin.Forms con almacenamiento de datos en SQLite. Para la cual crearemos la solución y proyecto de nombre AppLogin haciendo uso de Visual Studio y todas las pruebas serán realizadas en un equipo móvil físico con Sistema Operativo Android, esto no restringe el uso de emuladores.

Requisitos:
Microsoft Visual Studio Community 2019.
Xamarin.Froms - XAML.
SQLite - Gestión de datos local.

Crear Proyecto:
Crearemos el proyecto para las plataformas de Android y iOS desde el Visual Studio 2019.

Aplicación móvil (Xamarin.Froms) y clic en siguiente
Ingresamos el nombre, la ubicación y clic en Crear

Seleccionamos la plantilla En Blanco, marcamos para las plataformas de Android y iOS y para finalizar clic en OK

Estructura del Proyecto:
Ahora describiremos la estructura del proyecto que acabamos de crear:

Se crearon 3 proyectos:

El primero es AppLogin, proyecto portable en el que escribiremos el código común de la aplicación. En los proyectos AppLogin.Android y AppLogin.iOS se implementará lo que se requería de acuerdo a nuestra necesidad por cada plaforma. Para aclarar que en este artículo sólo trataremos el desarrollo para Android por ser las plataformas de terceros, iOS lo veremos más adelante.

Recordemos que Xamarin.Forms es una plataforma para desarrollar aplicaciones para plataformas iOS, Android , Windows Phone , Windows Store y Mac usando el lenguaje de programación C#. Compuesto por una serie de componentes que permite definir interfaces de usuario para distintas plataformas desde una misma base de código.

Xamarin.Forms está orientado a construir aplicaciones con interfaces de usuario sencillas, donde es más importante la capacidad de compartir código que el brindar interfaces de usuario avanzadas y personalizadas para cada plataforma, sin embargo, existe la posibilidad de hacer la personalización de los componentes a cada plataforma heredando nuestro componente básico de Xamarin.Forms a uno que se implementara en el proyecto de iOS y Android , y ahí podemos usar instrucciones típicas (equivalentes en .NET) de Objective-C y Java respectivamente.

Crear directorios:
Después de haber creado el proyecto, iniciaremos con la creación de los siguientes directorios: Data, Models y Views:

Crear clases:
En el directorio Data crearemos las siguientes clases: DataBase.cs, TaskExtensions.cs y UserDB.cs. Seguidamente en el directorio Models creamos la clase User.cs.

Diseño de Interfaz:
En el directorio Views agregamos un nuevo elemento de tipo Página de Contenido para XAML de nombre de Login.xaml, al crear el .xaml también se creará el Login.xaml.cs, aclaremos las diferencias:

.XAML: Es el lenguaje de marcado baso en XML creado por Microsoft, es decir es el quien define la interfaz de usuario para la aplicación. 
.XAML.CS: Es el encargo de almacenar el CodeBehind en relación al diseño y otras lógicas que programación que pueda existir sobre la necesidad y funcionalidad por la que fue creada.

Ahora iniciaremos definiendo la interfaz de nuestra aplicación, para lo cual - iniciaremos - abriendo el archivo MainPage.xaml del proyecto AppLogin y agregamos las siguientes propiedades:

<Image Source="LogoDIAbetes.jpg" HeightRequest="140" WidthRequest="140" FlexLayout.AlignSelf="Center" BackgroundColor="Transparent" />
<Button x:Name="btnLogin" FontSize="Medium" BorderColor="Black" FlexLayout.AlignSelf="Stretch" CornerRadius="5"  HorizontalOptions="CenterAndExpand" Text="Iniciar Sesión" Clicked="btnLogin_Clicked" TextColor="White" BackgroundColor="#3399ff"/>

Seguidamente abrimos el archivo Login.xaml y agregamos las siguientes propiedades:
                <Image Source="LogoDIAbetes.jpg" HeightRequest="140" WidthRequest="140" FlexLayout.AlignSelf="Center" BackgroundColor="Transparent" />
<Label TextColor="#3399ff" FontAttributes="Bold" Text="Iniciar Sesión" FlexLayout.AlignSelf="Center" FontSize="25"/>
<Entry x:Name="userNameEntry" ReturnType="Next" Placeholder="Email" FontSize="Medium" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand"  TextColor="Black" />
<Entry x:Name="passwordEntry" ReturnType="Done" IsPassword="True" Placeholder="Password" FontSize="Medium" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand"  TextColor="Black" />
<Button x:Name="loging" Clicked="loging_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#00b33c"  CornerRadius="5" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" Text="Iniciar sesión"></Button>
<Label x:Name="forgetLabel" Text="¿Olvidó su contraseña?" TextColor="Blue" FontSize="15" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>

Desarrollo de código:
Abrimos el archivo o clase MainPage.xaml.cs y agregamos la creamos  la tarea asíncrona btnLogin_Clicked que se encargará de llamar a la Página de Contenido para XAML de nombre de Login.xaml:

        private async void btnLogin_Clicked(object sender, EventArgs e)
        {           
            await this.Navigation.PushAsync(new Login());
        }

Seguidamente abrir el archivo o clase DataBase.cs y agregamos las siguientes instrucciones:

    public class DataBase
    {
        public const string DatabaseFilename = "DIAbetesSQLite.db3";

        public const SQLiteOpenFlags Flags =           
            SQLiteOpenFlags.ReadWrite | // open the database in read/write mode
            SQLiteOpenFlags.Create |    // create the database if it doesn't exist
            SQLiteOpenFlags.SharedCache;// enable multi-threaded database access

        public static string DatabasePath
        {
            get
            {
                var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                return Path.Combine(basePath, DatabaseFilename);
            }
        }

    }

A continuación abrir el archivo o clase TaskExtensions.cs y agregamos las siguientes instrucciones:

    public static class TaskExtensions
    {       
        public static async void SafeFireAndForget(this Task task,
            bool returnToCallingContext,
            Action<Exception> onException = null)
        {
            try
            {
                await task.ConfigureAwait(returnToCallingContext);
            }

            // if the provided action is not null, catch and
            // pass the thrown exception
            catch (Exception ex) when (onException != null)
            {
                onException(ex);
            }
        }
    }

Luego abrimos el archivo o clase User.cs y agregamos los siguientes atributos que representarán el modelo de datos de nuestros usuarios:

    public class User
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string email { get; set; }
        public string name { get; set; }
        [MaxLength(12)]
        public string password { get; set; }
        [MaxLength(10)]
        public string phone { get; set; }
    }

Ahora abrimos el archivos o clase UserDB.cs y creamos las siguientes instrucciones:

El método whereUser es el encargado de validar los datos de usuarios que fueron ingresados previamente. También puede revisar Xamarin.Forms - CRUD con SQLite.

    public class UserDB
    {
        static readonly Lazy<SQLiteAsyncConnection> lazyInitializer = new Lazy<SQLiteAsyncConnection>(() =>
        {
            return new SQLiteAsyncConnection(DataBase.DatabasePath, DataBase.Flags);
        });

        static SQLiteAsyncConnection Database => lazyInitializer.Value;
        static bool initialized = false;

        public UserDB()
        {
            InitializeAsync().SafeFireAndForget(false);
        }

        async Task InitializeAsync()
        {
            if (!initialized)
            {
                if (!Database.TableMappings.Any(m => m.MappedType.Name == typeof(User).Name))
                {
                    await Database.CreateTablesAsync(CreateFlags.None, typeof(User)).ConfigureAwait(false);
                    initialized = true;
                }
            }
        }

        #region metodos login
        public IEnumerable<User> whereUser(string strEmail, string strPwd)
        {
            var result = Database.QueryAsync<User>("Select * from User Where email=? and password=?", strEmail, strPwd);

            return result.Result;
        }
        #endregion
    }

Para finalizar abrimos archivo Login.xaml.cs y creamos las siguientes instrucciones:

La tarea asíncrono loging_Clicked es el encargado de realizar las validaciones de cara a la interfaz del usuario.

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Login : ContentPage    {

        UserDB userData = new UserDB();
        public Login()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Botón para validar e ingresar a la pantalla principal de la app
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void loging_Clicked(object sender, EventArgs e)
        {
            if (await ValidateForm())
            {
                IEnumerable<User> result = userData.whereUser(userNameEntry.Text.Trim(), passwordEntry.Text.Trim());

                if (result.Count() == 0)
                {
                    await DisplayAlert("Alerta", "Email o Password Incorrectos.", "OK");
                }
                else if (result.Count() == 1)
                {
                    await Navigation.PushAsync(new UsersList());
                }
                else if (result.Count() >= 1)
                {
                    await DisplayAlert("Alerta", "Existe más de una cuenta registada, favor de solicitar la correción de la cuenta.", "OK");
                    //await Navigation.PushAsync(new DuplicateAccountSendEmail());
                }
            }
        }

        /// <summary>
        /// Validar las propiedades de la pantalla de envio de email
        /// </summary>
        /// <returns></returns>
        private async Task<bool> ValidateForm()
        {
            //Valida si el valor en el Entry txtTo se encuentra vacio o es igual a Null
            if (String.IsNullOrWhiteSpace(userNameEntry.Text))
            {
                await this.DisplayAlert("Advertencia", "El campo Email es obligatorio.", "OK");
                return false;
            }
            else
            {
                //Valida que el formato del email sea valido
                bool isEmail = Regex.IsMatch(userNameEntry.Text, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase);
                if (!isEmail)
                {
                    await this.DisplayAlert("Advertencia", "El formato del Email es incorrecto.", "OK");
                    return false;
                }
            }

            //Valida si el valor en el Entry txtSubject se encuentra vacio o es igual a Null
            if (String.IsNullOrWhiteSpace(passwordEntry.Text))
            {
                await this.DisplayAlert("Advertencia", "El campo Password es obligatorio.", "OK");
                return false;
            }

            return true;
        }

    }

Resultado:
Al finalizar la edición de esté post la interfaz a variado, sin embargo la funcionalidad son las mismas:

 


Comparto el vídeo 📹 acerca de lo desarrollado de acuerdo a la descripción de este post publicado, todas las pruebas fueron validados en plataforma 📱 para Android.


Mayor información disponible en:
👉 Saber más de XAML

Descarga la fuente de:
En proceso de carga...

Nuevamente gratitud a Dios y 😊 de antemano gracias a todos ustedes por la acogida de este nuevo post publicado, bendiciones 🙏 y fuerte 💪 abrazo...!!!

Comentarios

Entradas más populares de este blog

Habilitar Usuario HR Oracle

Al realizar la primera instalación del Oracle, el usuario HR por defecto está bloqueado y por ende no podemos loguearnos como dicho usuario, lo que debe hacer son los siguiente pasos, aplicables para Linux o Windows.
1. Conectarse como usuario system o sysdba + contraseña haciendo uso del comando connect.
Usuario: system
Password: xxxx 


2. Hacer uso  del comando alter user hr account unlock desbloqueamos la cuenta.
alter user hr account unlock;

3. Escribimos el comando alter user HR identified by hr; con esto estamos diciendo que la contraseña será hr.

alter user HR identified by hr;

4. Ahora testeamos la conexión con el comando - conn hr/hr@xe. Si deseas después de conectarnos se puede realizar un select a la tabla employees del hr.


Resultado del select realizado
5. Con todos estos pasos realizados ya podemos logearnos desde cualquier IDE como el usuario hr  y la contraseña hr que definimos en el paso 3. 
Para finalizar nos loguearemos con el IDE Oracle SQL Developer.

Espero les sea de utilidad,…

Usuario SYS y SYSTEM - ORACLE

Usuario SYS y SYSTEM
Ambos usuario son creados de forma automática al crear la base de datos ORACLE y se otorga el rol de DBA.

SYS (password por defecto: CHANGE_ON_INSTALL).
SYSTEM (password por defecto: MANAGER).

Lo que se recomienda es cambiar el password de ambos usuarios por el tema de seguridad.

SYS:
Todas las tablas y vistas para el diccionario de datos de la base de datos están almacenados en el esquema SYS. Estas tablas y vistas son críticas para el funcionamiento de la base de datos ORACLE. Para mantener la integridad del diccionario de datos, las tablas del esquema SYS son manipulados solo por la base de datos. Nunca se debería modificar algo o crear tablas en el esquema del usuario SYS.

SYSTEM:
El usuario SYSTEM se utiliza para crear tablas y vistas adicionales que muestran información administrativa, tablas internas y vistas utilizado por varias opciones y herramientas de la base de datos ORACLE. No se recomienda utilizar el esquema SYSTEM para almacenar tablas de interés para usu…

Parámetro de entrada y salida – PL/SQL

Parámetro de entrada y salida – PL/SQL:
Los parámetros de entrada y salida no son los parámetros de inicialización de la base de datos ORACLE. Los parámetros de entra y salida son utilizados mayormente en implementaciones de funciones, procedimientos almacenados o bloques de código bajo el lenguaje del PL/SQL, se considera que ambos parámetros (entra y salida) puedan realizar operaciones en el mismo bloque PL/SQL, es decir, si enviamos un parámetro de entrada hará que cumpla cierta operación y retornara los valores de salida de dicha operación procesada de acuerdo al parámetro de ingresado. Es de acuerdo al caso que nos presenta en la implementación.
Algo importante al definir los parámetros, es saber y considerar cuántos tipos de parámetro existe si solo hablamos de entrada y salida, en realidad mi determinación seria 3 tipos:

Parámetros:

IN – entrada
OUT – salida
IN OUT – entrada salida

Parámetro IN – entrada:
El comportamiento común de estés tipos de parámetros es estar siempre pendiente d…