Persistencia en dispositivos móviles - iOS
  • Introduction
  • Persistencia básica
    • El sistema de archivos
    • Serialización de clases
    • Property Lists
    • Preferencias de usuario
    • Ejercicios
  • SQLite
    • Introducción a SQLite en iOS
    • El API básico de SQLite
    • Frameworks de terceros
    • Ejercicios
  • ¡Hola Core Data!. Una aplicación de ejemplo
    • Introducción a Core Data
    • El stack de Core Data
    • Las entidades
    • Recuperar los datos
  • Modelos de datos en Core Data
    • Crear modelos
    • Entidades con clases propias
    • CRUD
    • Ejercicios
  • Más sobre modelos de datos
    • Tipos de datos transformables
    • Validaciones
    • El ciclo de vida de los objetos gestionados
    • Deshacer y rehacer operaciones
    • Ejercicios
  • Búsquedas en Core Data
    • Predicados
    • Ordenación
    • Ejercicios
  • Tablas en Core Data
    • El fetched results controller
    • Inicializar el "fetched results controller"
    • Mostrar los datos en la tabla
    • Refrescar la tabla
    • Secciones de tabla automáticas
    • Ejercicios
  • Migraciones de datos
    • Qué son las migraciones de datos
    • Versiones del modelo de datos
    • Migraciones ligeras
    • Migraciones pesadas
    • Ejercicios
    • Apéndice: migraciones en iOS<=9
  • Contextos múltiples
    • Múltiples contextos para trabajos en background
    • Comunicación entre contextos
    • Contextos anidados
    • Ejercicios
  • Persistencia como servicio
    • Backend as a Service
    • Gestión de usuarios en Firebase
    • Persistencia en Firebase
    • Ejercicios
  • Arquitecturas de aplicaciones en iOS
    • Model/View/Controller
    • Model/View/Presenter
    • Model/View/ViewModel
    • VIPER
    • Ejercicios parte I
    • Ejercicios parte II
    • Ejercicios parte III
Powered by GitBook
On this page
  • Uso de FMDB en proyectos Swift
  • Instalación de la librería
  • El API de FMDB

Was this helpful?

  1. SQLite

Frameworks de terceros

PreviousEl API básico de SQLiteNextEjercicios

Last updated 6 years ago

Was this helpful?

Ya hemos visto que no hay un API en Swift (ni en Objective-C) para usar SQLite y que tampoco es de esperar que aparezca ninguno, dado el énfasis que Apple hace en Core Data para las tareas de persistencia. No obstante esto no ha impedido que aparezcan librerías de terceros implementando un API para SQLite que sea de más alto nivel y más sencillo de usar en iOS.

Hay multitud de wrappers de SQLite en Swift. De ellos uno de los más conocidos es .

No obstante los frameworks más usados para SQLite siguen siendo Objective-C, el más conocido es probablemente . Vamos a ver una introducción muy básica a este framework

Uso de FMDB en proyectos Swift

Swift es una librería hecha en Objective-C pero ya sabemos que podemos mezclar Objective-C con Swift en un proyecto.

Instalación de la librería

Aunque la forma recomendada para instalar FMDB en un proyecto es a través del uso de CocoaPods probablemente es más simple importar directamente los fuentes. Para eso nos podemos de su .

Una vez descomprimido el .zip vamos al directorio fmdb-master/src/fmdb e importamos todos los archivos de este directorio a nuestro proyecto (menos el .plist, que no es necesario). Al importarlos, Xcode detectará que son archivos en Objective-C y nos preguntará si queremos crear el "bridging header". Le decimos que sí y se creará el fichero vacío <nombre-del-proyecto>-Bridging-Header.h, en el que añadiremos la siguiente línea:

#import "FMDB.h"

A partir de este momento ya podemos usar las clases de FMDB dentro de nuestro código Swift

El API de FMDB

Vamos a ver unos cuantos ejemplos de uso de la librería FMDB para que se vea que es bastante más fácil de usar que el API C. La librería tiene varias clases básicas (podéis consultar online la ). De ellas las dos más usadas en un código típico son:

  • FMDatabase, que es un objeto que representa a la base de datos. Es la clase más importante y con la que se va a interactuar la mayor parte del tiempo. Se usa para abrir/cerrar la conexión y también para ejecutar las consultas.

  • FMResultSet, que encapsula un conjunto de registros resultado de una consulta de selección. Podemos ir iterando por el conjunto y obtener los campos del registro actual, al igual que con el API C, pero de forma mucho más sencilla: por ejemplo podemos obtener el valor de un campo por nombre, y las llamadas están bastante simplificadas para adaptarse mejor a los casos de uso más típicos.

Por ejemplo, veamos cómo se abriría una base de datos, se ejecutaría una consulta de selección y se iría iterando por el conjunto de registros resultante

let dbPath = Bundle.main.path(forResource: "prueba", ofType: "db")
if let db = FMDatabase(path: dbPath) {
    if (!db.open()) {
        print("Error al abrir la bd: \(db.lastErrorMessage())")
    }
    else {
        if let resultSet = try? db.executeQuery("SELECT * FROM Personas", values: nil) {
            while (resultSet.next()) {
               print(resultSet.string(forColumn: "nombre"))
            }
        }
    }
}
  • Para inicializar la BD necesitamos el path y usamos el método de clase databaseWithPath

  • Abrir y cerrar la BD es tan sencillo como llamar a open y close. El método open devuelve un valor booleano que indica si se ha abierto o no correctamente. En caso de error en una operación de BD podemos acceder a más información sobre el mismo con los métodos lastErrorMessage o lastErrorCode.

Cuando se abre una BD que no existe, FMDB la crea automáticamente, se puede cambiar este comportamiento llamando a openWithFlags con los parámetros adecuados, en lugar de a open. También se puede usar una BD en memoria si se le pasa NULL como path a databaseWithPath

  • Las consultas se ejecutan con executeQuery y devuelven una instancia de la clase FMResultSet. Para iterar por el resultset usamos el método next.

  • Podemos obtener los campos del registro actual con una serie de métodos XXXForColumn:, donde la parte inicial del nombre es el tipo de datos de la columna (string, int, long, date,…). Obsérvese además que se accede a la columna por nombre y no por posición (aunque también se puede acceder por posición con XXXForColumnIndex:).

Por supuesto podemos ejecutar consultas con parámetros. El método executeQuery: admite una lista de argumentos con los valores, por ejemplo:

let rs = db.executeQuery("SELECT * FROM alumnos
                       where fecha_nacimiento<?", values:[fecha_ref];

Para ejecutar una consulta de actualización se usa executeUpdate: en lugar de executeQuery.

También podemos usar de forma sencilla parámetros por nombre (algo que en el API C es un poco tedioso). Basta con crear un diccionario con los nombres de los parámetros como claves y los valores deseados

let query = "INSERT INTO personas (dni, nombre) VALUES (:dni, :nombre)"
let datos = [
    "dni" : "1222333K",
    "nombre": "Pepito"
]
db.executeUpdate(query, withParameterDictionary: datos)
SQLite.swift
FMDB
bajar directamente el .zip de FMDB
repositorio de Github
referencia del API