Advertisement
  1. Code
  2. Mobile Development

Una introducción a Xamarin.Forms y SQLite

Scroll to top

() translation by (you can also view the original English article)

En algún momento durante tu carrera en desarrollo móvil vas a tener que lidiar con datos. El manejo de datos significa más que procesar y mostrar información al usuario final. Vas a necesitar almacenar esta información en algún lugar y ser capaz de acceder a ella fácilmente. Gracias a Xamarin y al software de código abierto puedes almacenar tus datos fácilmente usando SQLite, que es una plataforma probada en la industria.

1. Almacenamiento de datos

Así que ¿por qué necesitas preocuparte por los datos cuando se trata de tu aplicación? es debido a que la información se encuentra en todos lados. No puedes escapar de ella. No importa qué tipo de aplicación estés desarrollando, ya sea un juego o algún tipo de utilidad, vas a necesitar almacenar datos en algún momento. Estos datos pueden ser la información de un usuario, estadísticas o cualquier otra cosa en la que estén interesados ya sea tú o el usuario en algún punto durante el uso de tu aplicación.

En este momento asumamos que has decidido ir por la ruta de Xamarin.Forms ya que estás interesado en desarrollar para varias plataformas, no solamente en cuanto a la lógica de tu aplicación sino también en el caso de la capa de interfaz de usuario.

Muy bien. Pero ¿qué puedes hacer ahora que necesitas almacenar información dentro de tu aplicación?. No te preocupes, hay una solución muy simple para este problema, se trata de SQLite.

2. Introducción a SQLite

Ahora has visto el término SQLite un par de veces en este tutorial, es momento de entrar en materia. ¿Qué es SQLite exactamente? SQLite es un motor de bases de datos SQL transaccionales, de domino público y sin necesidad de configuración. Todo esto significa que cuentas con un mecanismo totalmente funcional para almacenar tus datos de manera estructurada. No solamente obtienes todo esto, sino que también cuentas con acceso al código fuente debido a que es de código abierto.

No cubriremos todas las características de SQLite en este tutorial, ya que hay demasiadas cosas por revisar. Ten la seguridad de que podrás crear fácilmente una estructura de tabla para almacenar datos y recuperarlos en tu aplicación. Estos son los conceptos en los que nos enfocaremos en este tutorial.

SQLite es ideal en el mundo de Xamarin.Forms por una razón muy sencilla. El motor SQLite está disponible fácilmente tanto en iOS como en Android. Esto significa que puedes usar esta tecnología directamente cuando eliges desarrollar una aplicación de Xamarin.Forms.

Para obtener acceso a la funcionalidad de SQLite en aplicaciones de Windows Phone se requiere un paso adicional que revisaremos un poco más adelante. Toda esta funcionalidad y accesibilidad multiplataforma es excelente, pero ¿cómo obtendremos acceso a las implementaciones de la plataforma nativa desde nuestro código C# en Xamarin.Forms? será a través de un buen paquete NuGet. Echemos un vistazo.

3. Creación de una aplicación

Comencemos creando una aplicación Xamarin.Forms simple. En este tutorial usaré una Mac ejecutando Xamarin Studio, pero de igual manera puedes usar Xamarin Studio o Visual Studio ejecutándose en una PC.

Paso 1: Crea un proyecto

Vamos a comenzar el proceso creando una nueva aplicación Xamarin.Forms. Para hacer esto, simplemente selecciona la familia de plantillas de proyecto Mobile Apps (Aplicaciones Móviles) que se encuentra a la izquierda y elige una de las plantillas de Xamarin.Forms a la derecha. Puedes usar ya sea la versión PCL o Shared (proyecto compartido) de la plantilla, pero para este caso usaré el proyecto PCL. Puedes seguir este tutorial usando cualquiera de las dos opciones, pero habrá una ligera diferencia más adelante si eliges la plantilla Shared.

Puedes asignarle el nombre que desees al proyecto. En mi caso lo nombraré IntroToSQLite. Después de hacer clic en el botón OK, tu IDE llevará a cabo el proceso de crear tu solución. Dicha solución contendrá cuatro proyectos:

  1. IntroToSQLite - PCL project
  2. IntroToSQLite.Android - Android project
  3. IntroToSQLite.iOS - iOS project
  4. IntroToSQLite.WinPhone - Windows Phone project (solamente en una PC)

Paso 2: Agrega soporte para SQLite

Ahora que tenemos configurada nuestra estructura básica para el proyecto, podemos comenzar a añadir acceso a SQLite a nuestro proyecto PCL. Necesitamos instalar un nuevo paquete en nuestro proyecto llamado SQLite.Net. Este es un contenedor .NET de SQLite que nos permitirá acceder a la funcionalidad SQLite nativa desde un proyecto Xamarin.Forms PCL o Shared.

Podemos acceder a este paquete NuGet haciendo clic con el botón derecho ya sea en Packages (Paquetes) o References (Referencias), dependiendo del IDE que estés usando, y luego seleccionado Add Package (o Reference, Añadir Paquete o Referencia). En el cuadro de búsqueda escribe sqlite.net. Esto te mostrará una colección de paquetes bastante extensa que puedes incluir en tu proyecto.

Add the SQLite NuGet packageAdd the SQLite NuGet packageAdd the SQLite NuGet package

Dado que yo elegí la ruta PCL para mi proyecto de Xamarin.Forms, tendré que seleccionar el paquete SQLite.Net PCL para incluirlo en mi proyecto. ¿Cuál debes elegir si estás usando un proyecto Shared? ninguno.

SQLite y Proyectos Shared (Compartidos)

Si elegiste la plantilla de proyecto Shared (Compartido) anteriormente en el tutorial, quizá te estés preguntando cómo lograr el acceso al paquete SQLite. La respuesta corta es que no puedes. Si recuerdas este tutorial anterior, no puedes añadir referencias a un proyecto Shared. Para lograr acceder a SQLite desde este tipo de proyecto, simplemente debes añadir el código fuente al mismo.

Agrega un poco de código

El paso final para añadir la funcionalidad SQLite al proyecto PCL es crear una interfaz que nos permitirá acceder al mundo de SQLite. La razón por la que hacemos esto es porque necesitamos acceder a la funcionalidad nativa en las diferentes plataformas, como lo vimos en un tutorial previo.

Comencemos definiendo una interfaz que nos dará acceso a la conexión con la base de datos SQLite. Dentro de tu proyecto PCL crea una nueva interfaz llamada ISQLite y reemplaza la implementación con lo siguiente:

1
using System;
2
using SQLite.Net;
3
4
namespace IntroToSQLite
5
{
6
    public interface ISQLite
7
  {
8
		SQLiteConnection GetConnection();
9
	}
10
}

Esta es la interfaz que implementaremos y a la que accederemos a través del DependencyService de las implementaciones nativas.

Paso 3: Define la base de datos

Ahora tenemos acceso a la funcionalidad SQLite, vamos a definir nuestra base de datos. Esta aplicación en particular va a ser muy simple y solamente vamos a almacenar algunos de nuestros pensamientos aleatorios a medida que aparezcan en nuestra mente.

Comencemos creando una clase que representará los datos almacenados en una tabla en particular. Llamemos a esta clase RandomThought.

1
using System;
2
using SQLite.Net.Attributes;
3
4
namespace IntroToSQLite
5
{
6
    public class RandomThought
7
	{
8
		[PrimaryKey, AutoIncrement]
9
		public int ID { get; set; }
10
		public string Thought { get; set; }
11
		public DateTime CreatedOn { get; set; }
12
13
		public RandomThought ()
14
		{
15
		}
16
	}
17
}

Como puedes ver, esta es una clase muy sencilla con tres propiedades. Dos de ellas son simplemente propiedades cotidianas normales, Thought y CreatedOn. Estas dos propiedades van a representar columnas en la base de datos de SQLite. La base de datos contendrá una tabla llamada RandomThought. La tercera propiedad, ID, también va a representar a una columna dentro de la tabla y contendrá un identificador único que podemos usar para hacer referencia a una fila de RandomThought específica dentro de la tabla.

El aspecto interesante de la propiedad ID es que está decorada con dos atributos, PrimaryKey y AutoIncrementPrimaryKey le indica a SQLite que ésta columna va a ser la clave primaria de la tabla, lo que significa que de forma predeterminada necesita ser única, además de que cuenta con un índice asignado a ella para acelerar la recuperación de información de la tabla al hacer referencia a una fila a través de esta columna.

AutoIncrement significa que, cuando insertamos un nuevo RandomThought en esta tabla, la columna ID será llenada automáticamente con el siguiente valor entero disponible. El próximo paso es crear esta tabla en la base de datos.

Me gusta crear una clase que represente a mi base de datos y mantener toda la lógica para acceder a ella y a sus tablas dentro de dicha clase. Para lograrlo crearé una clase llamada RandomThoughtDatabase:

1
using System;
2
using SQLite.Net;
3
using Xamarin.Forms;
4
using System.Collections.Generic;
5
using System.Linq;
6
7
namespace IntroToSQLite
8
{
9
    public class RandomThoughtDatabase
10
	{
11
		private SQLiteConnection _connection;
12
13
		public RandomThoughtDatabase ()
14
		{
15
			_connection = DependencyService.Get<ISQLite> ().GetConnection ();
16
			_connection.CreateTable<RandomThought> ();
17
		}
18
19
		public IEnumerable<RandomThought> GetThoughts() {
20
			return (from t in _connection.Table<RandomThought> ()
21
			        select t).ToList ();
22
		}
23
24
		public RandomThought GetThought(int id) {
25
			return _connection.Table<RandomThought> ().FirstOrDefault (t => t.ID == id);
26
		}
27
28
		public void DeleteThought(int id) {
29
			_connection.Delete<RandomThought> (id);
30
		}
31
32
		public void AddThought(string thought) {
33
			var newThought = new RandomThought {
34
				Thought = thought,
35
				CreatedOn = DateTime.Now
36
			};
37
38
			_connection.Insert (newThought);
39
		}
40
	}
41
}

Esta es una implementación muy simple ya que solamente contiene algunos métodos. Típicamente estas son algunas de las operaciones básicas que llevarás a cabo al tratar con una base de datos. Un punto a destacar es el constructor. Dentro del constructor estamos haciendo dos cosas.

En primer lugar, estamos usando la clase DependencyService para obtener una clase registrada que implementa la interfaz ISQLite e invoca a su método GetConnection.

En segundo lugar, usamos el método CreateTable en la clase SQLiteConnection para crear una tabla llamada RandomThought. Este método creará la tabla, si es que aún no existe, y saldrá de forma limpia si es que ya existe.

Obviamente puedes lograr tanta sofisticación con esta clase como desees añadiendo todo tipo de funcionalidad, pero estas operaciones por lo general son un buen punto de partida.

Paso 4: Agrega la implementación para iOS

La mayor parte del código que usamos para interactuar con la base de datos se encontrará en el proyecto PCL (o Shared). Pero aún necesitamos hacer algunos ajustes en las implementaciones nativas para que todo funcione correctamente.

El obstáculo principal que necesitamos resolver del lado nativo al usar SQLite es el lugar en el que vamos a almacenar el archivo real de la base de datos. Esto difiere de una plataforma a otra. Esto es lo que necesitamos para iOS.

Antes de que podamos añadir cualquier tipo de funcionalidad de SQLite al proyecto iOS, necesitamos agregar los paquetes SQLite.Net PCL así como SQLite.NET PCL - XamarinIOS Platform al proyecto. Puedes seguir el mismo procedimiento que llevaste a cabo en el Paso 2, asegurándote de añadir ambos paquetes al proyecto. Una vez que hayas hecho lo anterior puedes comenzar a escribir código SQLite dentro del proyecto iOS.

Vamos a crear una implementación de la interfaz ISQLite para iOS. Comienza creando una nueva clase y llamándola SQLite_iOS.

1
using System;
2
using System.IO;
3
using SQLite;
4
using IntroToSQLite.iOS;
5
using Xamarin.Forms;
6
7
[assembly: Dependency(typeof(SQLite_iOS))]
8
9
namespace IntroToSQLite.iOS
10
{
11
    public class SQLite_iOS: ISQLite
12
	{
13
		public SQLite_iOS ()
14
		{
15
		}
16
17
		#region ISQLite implementation
18
19
		public SQLite.Net.SQLiteConnection GetConnection ()
20
		{
21
			var fileName = "RandomThought.db3";
22
			var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
23
			var libraryPath = Path.Combine (documentsPath, "..", "Library");
24
			var path = Path.Combine (libraryPath, fileName);
25
26
			var platform = new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS ();
27
			var connection = new SQLite.Net.SQLiteConnection (platform, path);
28
29
			return connection;
30
		}
31
32
		#endregion
33
	}
34
}
35

De esta manera obtenemos acceso a la ubicación correcta para almacenar el archivo de la base de datos, creamos un nuevo objeto SQLiteConnection y lo enviamos de vuelta a nuestro proyecto PCL (o Shared). El atributo assembly de la parte superior del archivo se usa para identificar a esta clase como Dependency que puede ser recuperada a través del método Get en la clase DependencyService.

Paso 5: Agrega la implementación para Android

Este paso es muy similar al anterior. La única diferencia es que el código cambiará un poco debido a que la ubicación del archivo de la base de datos será diferente. Aún necesitas agregar los paquetes apropiados al proyecto Android (SQLite.Net PCL y SQLite.NET PCL - XamarinAndroid) como lo hiciste anteriormente. Una vez que hayas hecho eso puedes agregar el código adecuado en una nueva clase llamada SQLite_Android.

1
using System;
2
using System.IO;
3
using Xamarin.Forms;
4
using IntroToSQLite.Android;
5
6
[assembly: Dependency(typeof(SQLite_Android))]
7
8
namespace IntroToSQLite.Android
9
{
10
    public class SQLite_Android: ISQLite
11
	{
12
		public SQLite_Android ()
13
		{
14
		}
15
16
		#region ISQLite implementation
17
18
		public SQLite.Net.SQLiteConnection GetConnection ()
19
		{
20
			var fileName = "RandomThought.db3";
21
			var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
22
			var path = Path.Combine (documentsPath, fileName);
23
24
			var platform = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid ();
25
			var connection = new SQLite.Net.SQLiteConnection (platform, path);
26
27
			return connection;
28
		}
29
30
		#endregion
31
	}
32
}
33

Ahora tienes una implementación funcional de la interfaz ISQLite desde la perspectiva de tu aplicación Android.

Paso 6: Agrega la implementación para Windows Phone

No voy a crear la implementación para Windows Phone, ya que estoy ejecutando esta aplicación desde una Mac, pero tú puedes hacerlo si lo deseas.

El primer paso es añadir soporte para SQLite a tu proyecto Windows Phone. Como mencioné anteriormente, SQLite viene integrado de forma predeterminada en iOS y Android. No es lo mismo en el caso de Windows Phone, pero éste tiene soporte para SQLite. Para instalarlo puedes seguir las instrucciones que se encuentran en el sitio web de Xamarin.

Después de instalar SQLite el proceso para añadir la funcionalidad a Windows Phone será casi exactamente el mismo, pero los paquetes que deben instalarse son SQLite.Net PCL y SQLite.Net PCL - WindowsPhone 8 Platform. Con estos paquetes instalados puedes crear la implementación para Windows Phone en la interfaz ISQLite.

1
using System;
2
using System.IO;
3
using Xamarin.Forms;
4
using IntroToSQLite.WinPhone;
5
6
[assembly: Dependency(typeof(SQLite_WinPhone)]
7
8
namespace IntroToSQLite.WinPhone
9
{
10
    public class SQLite_WinPhone: ISQLite
11
    {
12
		public SQLite_WinPhone ()
13
		{
14
		}
15
16
		#region ISQLite implementation
17
18
		public SQLite.Net.SQLiteConnection GetConnection ()
19
		{
20
			var fileName = "RandomThought.db3";
21
			var path = Path.Combine (ApplicationData.Current.LocalFolder.Path, fileName);
22
23
			var platform = new SQLite.Net.Platform.WindowsPhone8.SQLitePlatformWP8 ();
24
			var connection = new SQLite.Net.SQLiteConnection (platform, path);
25
26
			return connection;
27
		}
28
29
		#endregion
30
	}
31
}
32

Ahí lo tienes. Ahora todas tus implementaciones nativas están completas. Es momento de darle una interfaz de usuario a esta aplicación y de introducir tu información a la base de datos.

Paso 7: Agregando la interfaz de usuario

Dado que este tutorial trata sobre el tema de Xamarin.Forms, voy a suponer que al menos tienes conocimientos básicos sobre cómo trabajar en Xamarin.Forms. Con esta premisa en mente no voy a entrar en muchos detalles con respecto al proceso de creación de la interfaz de usuario. Si necesitas más información general sobre Xamarin.Forms revisa mis otros tutoriales de Xamarin.Forms en Tuts+.

La interfaz de usuario estará compuesta por dos páginas separadas. La primera contendrá una lista de todos los pensamientos que hayamos introducido, mientras que la segunda página permitirá que el usuario escriba un nuevo pensamiento. Vamos a construir estas páginas.

Crea el ListView

Primero nos enfocaremos en crear la primera página que contendrá una lista de objetos RandomThought. Comienza creando un nuevo archivo en el proyecto PCL (o Shared) y asígnale el nombre RandomThoughtsPage. Reemplaza la implementación predeterminada con lo siguiente:

1
using System;
2
using Xamarin.Forms;
3
4
namespace IntroToSQLite
5
{
6
    public class RandomThoughtsPage: ContentPage {
7
		private RandomThoughtDatabase _database;
8
		private ListView _thoughtList;
9
10
		public RandomThoughtsPage (RandomThoughtDatabase database)
11
		{
12
			_database = database;
13
			Title = "Random Thoughts";
14
			var thoughts = _database.GetThoughts ();
15
16
			_thoughtList = new ListView ();
17
			_thoughtList.ItemsSource = thoughts;
18
			_thoughtList.ItemTemplate = new DataTemplate (typeof(TextCell));
19
			_thoughtList.ItemTemplate.SetBinding (TextCell.TextProperty, "Thought");
20
			_thoughtList.ItemTemplate.SetBinding (TextCell.DetailProperty, "CreatedOn");
21
22
			var toolbarItem = new ToolbarItem {
23
				Name = "Add",
24
				Command = new Command(() => Navigation.PushAsync(new ThoughtEntryPage(this, database)))
25
			};
26
27
			ToolbarItems.Add (toolbarItem);
28
29
			Content = _thoughtList;
30
		}
31
32
		public void Refresh() {
33
			_thoughtList.ItemsSource = _database.GetThoughts ();
34
		}
35
	}
36
}
37

La mayor parte del trabajo efectuado en esta clase se encuentra en el constructor. Este nos permite pasar una instancia de RandomThoughtsDatabase para obtener todos los pensamientos guardados. Vamos a establecer la propiedad Title de la página usando el valor "Random Thoughts" ("Pensamientos aleatorios"), obtendremos todos los pensamientos existentes, crearemos una nueva instancia de un ListView y crearemos un ToolbarItem que nos permitirá hacer clic en un botón para cargar la página de captura. Aun no hemos implementado lo anterior, pero lo haremos pronto.

Para lograr que nuestra nueva página RandomThoughtsPage aparezca en la pantalla necesitamos hacer una pequeña modificación en el archivo App.cs. Dentro de este archivo modifica el método GetMainPage para que se vea así:

1
public static Page GetMainPage ()
2
{ 
3
    var database = new RandomThoughtDatabase ();
4
5
    return new NavigationPage (new RandomThoughtsPage (database));
6
}

El método GetMainPage ahora crea una nueva instancia de nuestra clase RandomThoughtDatabase y devuelve una nueva instancia de RandomThoughtsPage. Con este cambio nuestras aplicaciones iOS y Android deberán verse más o menos así:

Random Thoughts page for iOSRandom Thoughts page for iOSRandom Thoughts page for iOS
Random Thoughts page for AndroidRandom Thoughts page for AndroidRandom Thoughts page for Android

Crea la página de captura

Ahora tenemos una página con una lista para todos nuestros objetos RandomThought, pero no tenemos manera de introducir nuevos objetos. Para hacer esto crearemos otra página similar a la anterior. Crea un nuevo archivo en tu proyecto PCL (o Shared) y asígnale el nombre ThoughtEntryPage. Reemplaza la implementación predeterminada con lo siguiente:

1
using System;
2
using Xamarin.Forms;
3
4
namespace IntroToSQLite
5
{
6
    public class ThoughtEntryPage: ContentPage {
7
		private RandomThoughtsPage _parent;
8
		private RandomThoughtDatabase _database;
9
10
		public ThoughtEntryPage ( RandomThoughtsPage parent, RandomThoughtDatabase database)
11
		{
12
			_parent = parent;
13
			_database = database;
14
			Title = "Enter a Thought";
15
16
			var entry = new Entry ();
17
			var button = new Button {
18
				Text = "Add"
19
			};
20
21
			button.Clicked += async (object sender, EventArgs e) => {
22
				var thought = entry.Text;
23
24
				_database.AddThought(thought);
25
26
				await Navigation.PopAsync();
27
28
29
				_parent.Refresh();
30
			};
31
32
			Content = new StackLayout {
33
				Spacing = 20,
34
				Padding = new Thickness(20),
35
				Children = { entry, button },
36
			};
37
		}
38
	}
39
}
40

En esta clase todo el trabajo se lleva a cabo dentro del constructor. Obtenemos una referencia a la página padre, RandomThoughtsPage, así como a la base de datos. El resto es código básico de configuración con un objeto Entry para escribir texto y un Button.

Una vez que el usuario pulse el Button usamos la base de datos para añadir el nuevo pensamiento, cerramos la página, regresamos a la página que tiene la lista e invocamos al método Refresh para actualizar el ListView. Una vez que esto se encuentre configurado podemos ejecutar para escribir algunos valores.

Escribiendo pensamientos

Así es como se ve la pantalla para escribir algunos de tus pensamientos en iOS y Android:

Adding thoughts on iOSAdding thoughts on iOSAdding thoughts on iOS
Adding thoughts on AndroidAdding thoughts on AndroidAdding thoughts on Android

Viendo la lista

Después de que hayas escrito algunos pensamientos, tu lista se verá más o menos así:

Listing thoughts on iOSListing thoughts on iOSListing thoughts on iOS
Listing thoughts on AndroidListing thoughts on AndroidListing thoughts on Android

Conclusión

Ahí lo tienes. Ahora puedes añadir la funcionalidad de una base de datos a tu aplicación Xamarin.Foms para almacenar y recuperar cualquier tipo de información con facilidad.

Para continuar con tu camino en el aprendizaje de Xamarin.Forms y SQLite te propongo el siguiente desafío. Intenta mejorar esta aplicación para permitir eliminar pensamientos y actualiza la página de la lista de manera similar a como funciona la página de captura. Buena suerte y disfruta programando.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.