Obtener fácilmente los datos básicos con Magical Record
Spanish (Español) translation by CYC (you can also view the original English article)
Magical Record, creado por Saul Mora , es una biblioteca de código abierto que hace que trabajar con Core Data sea más fácil y más elegante. La biblioteca se inspiró en el patrón de registro activo que también se encuentra en Ruby on Rails. ¡Este tutorial te enseñará cómo usar Magical Record en tus propias aplicaciones!
Entonces, ¿por qué Registro Mágico ? Si has estado desarrollando para iOS o OS X durante algún tiempo, es probable que hayas probado Core Data. Esto significa que sabe que puede ser un poco engorroso configurar una pila de Core Data y, para ser honesto, trabajar con Core Data puede ser un poco complejo debido principalmente a su sintaxis detallada. Por ejemplo, obtener datos de un almacén persistente es bastante detallado, especialmente cuando se compara con la forma en que una aplicación de Ruby on Rails maneja esta tarea.
Prerrequisitos
A pesar de que Magical Record hace que el trabajo con Core Data sea más fácil, es clave que tenga un buen conocimiento de Core Data si decide utilizarlo en un proyecto. A pesar de su nombre, Magical Record no realiza ningún tipo de magia detrás de escena que haga que Core Data funcione de manera diferente. En otras palabras, si tiene problemas en algún momento, es crucial que entienda cómo funciona Core Data internamente para poder solucionar cualquier problema que pueda surgir en el camino.
Requerimientos
Desde la introducción de Magical Record, los requisitos se han incrementado a iOS 5.0 (o superior) u OS X 10.7 (o superior). También vale la pena mencionar que Magical Record admite ARC fuera de la caja.
Notas magicas
La mejor manera de mostrarle lo que Magical Record tiene para ofrecer es crear una aplicación que haga uso de esta gran biblioteca. Le mostrará lo fácil que es comenzar con Magical Record y, desde el principio, le mostrará lo que implica crear un proyecto con Core Data y Magical Record. La aplicación que estamos a punto de crear es una aplicación sencilla para tomar notas en la que el usuario puede crear, actualizar y eliminar notas, un buen candidato para Core Data.
Ya que ha leído hasta aquí, asumo que está familiarizado con el desarrollo de iOS y que tiene una comprensión básica de Core Data. En este artículo, me centraré principalmente en el aspecto Datos básicos de la aplicación, lo que significa que no analizaré cada fragmento de código en detalle.
Paso 1: Configuración del proyecto
Comience creando un nuevo proyecto basado en la plantilla de aplicación de vista única (figura 1) y asígnele el nombre de Notas mágicas (figura 2). Configure la familia de dispositivos para iPhone y active ARC marcando la casilla de verificación Usar conteo automático de referencias . No usaremos Storyboards o pruebas de unidad en este tutorial.




Paso 2: Añadir registro mágico
Ya que usaremos Datos Básicos en este proyecto, no olvide vincular su proyecto con el marco de Datos Básicos. Dado que este es un tutorial más avanzado, asumo que ya sabes cómo hacerlo.
Agregar la biblioteca de Registro Mágico a tu proyecto no requiere ninguna magia. Descargue la última versión de GitHub , abra el archivo y arrastre la carpeta llamada MagicalRecord a su proyecto Xcode. Asegúrese de copiar también el contenido de la carpeta en su proyecto marcando la casilla marcada como Copiar elementos en la carpeta del grupo de destino (si es necesario) y no olvide agregar la biblioteca de Registro Mágico al destino de Notas Mágicas (figura 3). Un enfoque alternativo para agregar Magical Record a su proyecto es usar CocoaPods .


Para utilizar Magical Record en sus clases, necesitamos importar un archivo de encabezado, CoreData + MagicalRecord.h . Sin embargo, dado que usaremosMagical Record bastante en este tutorial, es mucho más conveniente mover esta declaración de importación al archivo Prefix.pch de su proyecto . Esto asegurará que Magical Record esté disponible en cada clase de su proyecto.
Por defecto, todos los métodos de Registro Mágico tienen el prefijo MR_ . Puede omitir el prefijo MR_ agregando una línea adicional al archivo Prefix.pch de su proyecto , #define MR_SHORTHAND . Es importante que agregue esta línea antes de importar el archivo de encabezado del registro mágico.
1 |
|
2 |
//
|
3 |
// Prefix header for all source files of the 'Magical Notes' target in the 'Magical Notes' project
|
4 |
//
|
5 |
|
6 |
#import <Availability.h>
|
7 |
|
8 |
#ifndef __IPHONE_4_0
|
9 |
#warning "This project uses features only available in iOS SDK 4.0 and later."
|
10 |
#endif
|
11 |
|
12 |
#ifdef __OBJC__
|
13 |
#import <UIKit/UIKit.h>
|
14 |
#import <Foundation/Foundation.h>
|
15 |
|
16 |
#define MR_SHORTHAND
|
17 |
#import "CoreData+MagicalRecord.h"
|
18 |
#endif
|
Paso 3: Crear un modelo de datos del núcleo
Antes de configurar la pila de Core Data, necesitamos crear un modelo de Core Data. El modelo de Datos Básicos para este proyecto es simple, ya que consta de una sola entidad llamada Nota . La entidad Nota tiene cuatro atributos, fecha , título , cuerpo y palabras clave . El título, el cuerpo y las palabras clave son de tipo cadena , mientras que la fecha es de tipo fecha .
Comience creando un nuevo modelo de Core Data y llámelo MagicalNotes (figura 4). Cree la entidad Nota y agregue los cuatro atributos como se describe arriba (figura 5).




Antes de continuar, debemos crear una subclase NSManagedObject personalizada para la entidad Note . Esto es importante ya que Magical Record agrega una serie de métodos de clase útiles a la clase NSManagedObject , lo que facilitará mucho el trabajo con la entidad Note como verá en unos minutos. Seleccione la entidad Note en su modelo de Core Data, cree un nuevo archivo, seleccione la pestaña Core Data a la izquierda y elija la opción de subclase NSManagedObject a la derecha (figura 6).


Paso 4: Crear la pila de datos Core
Configurar una pila de Core Data es bastante trabajo si no usas una de las plantillas de Xcode provistas. Con Magical Record, sin embargo, este no es el caso. Dirígete a la aplicación: didFinishLaunchingWithOptions: método de tu delegado de aplicación y agrega el siguiente fragmento de código.
1 |
|
2 |
[MagicalRecord setupCoreDataStack]; |
Eso es todo al respecto. De forma predeterminada, el nombre de la tienda que Magical Record crea para usted es idéntico al nombre de su aplicación. Sin embargo, puede personalizar el nombre de la tienda invocando setupCoreDataStackWithStoreNamed: en sulugar y pasando el nombre de la tienda.
Detrás de las escenas, Magical Record creará una instancia de un contexto de objeto gestionado en el hilo principal, así como un coordinador de tienda persistente y un modelo de objeto gestionado. ¿Qué tan mágico es eso?
Registro: la capacidad de registrar mensajes y errores de datos básicos en la consola está integrada en Magical Record. Eche un vistazo a la consola después de construir y ejecutar su aplicación por primera vez. Los registros en la consola le muestran exactamente lo que Magical Record está haciendo entre bastidores.
Paso 5: Sentar las bases
Antes de que podamos comenzar a crear nuevas notas, primero necesitamos un trabajo duro. Revise la aplicación del delegado de su aplicación: didFinishLaunchingWithOptions:método e inicialice un controlador de navegación con el controlador de vista principal como su controlador de vista raíz. Echar un vistazo a la implementación completa de aplicaciones: didFinishLaunchingWithOptions: .
1 |
|
2 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
3 |
// Setup Core Data Stack
|
4 |
[MagicalRecord setupCoreDataStack]; |
5 |
|
6 |
// Initialize View Controller
|
7 |
self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewController" bundle:nil]; |
8 |
|
9 |
// Initialize Navigation Controller
|
10 |
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:self.viewController]; |
11 |
|
12 |
// Initialize Window
|
13 |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
14 |
[self.window setRootViewController:nc]; |
15 |
[self.window makeKeyAndVisible]; |
16 |
|
17 |
return YES; |
18 |
}
|
Mostraremos las notas en una vista de tabla, así que comience agregando una salida para una vista de tabla en el archivo de encabezado del controlador de vista principal. Seleccione el archivo XIB del controlador de vista principal y arrastre una instancia de UITableView en la vista del controlador de vista. No olvide asignar el propietario del archivo como fuente de datos y delegado de la vista de tabla . Además, asegúrese de conectar la salida de la vista de tabla del propietario del archivo con la vista de tabla que acabamos de agregar a su vista.
1 |
|
2 |
#import <UIKit/UIKit.h>
|
3 |
|
4 |
@interface MTViewController : UIViewController |
5 |
|
6 |
@property (nonatomic, weak) IBOutlet UITableView *tableView; |
7 |
|
8 |
@end
|
En el archivo de implementación del controlador de vista principal, agregue una propiedad privada denominada notas a la extensión de clase en la parte superior. Asegúrese de que la propiedad sea de tipo NSMutableArray . La propiedad de notas almacenará las notas que obtengamos del almacén de datos y servirá como fuente de datos de la vista de tabla.
1 |
|
2 |
#import "MTViewController.h"
|
3 |
|
4 |
@interface MTViewController () |
5 |
|
6 |
@property (nonatomic, strong) NSMutableArray *notes; |
7 |
|
8 |
@end
|
En el método viewDidLoad del controlador de vista , configuramos la vista llamando a setupView en el controlador de vista principal. Esto no es más que un método auxiliar para mantener el método viewDidLoad conciso y ordenado. En setupView , agregamos un botón de edición y adición a la barra de navegación y recuperamos las notas del almacén de datos invocando el método fetchNotes .
1 |
|
2 |
- (void)viewDidLoad { |
3 |
[super viewDidLoad]; |
4 |
|
5 |
// Setup View
|
6 |
[self setupView]; |
7 |
}
|
1 |
|
2 |
- (void)setupView { |
3 |
// Create Edit Button
|
4 |
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:@"Edit" style:UIBarButtonItemStyleBordered target:self action:@selector(editNotes:)]; |
5 |
self.navigationItem.leftBarButtonItem = editButton; |
6 |
|
7 |
// Create Add Button
|
8 |
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:@"Add" style:UIBarButtonItemStyleBordered target:self action:@selector(addNote:)]; |
9 |
self.navigationItem.rightBarButtonItem = addButton; |
10 |
|
11 |
// Fetch Notes
|
12 |
[self fetchNotes]; |
13 |
}
|
Podría sorprenderte que el método fetchNotes sea solo una línea de código. Todo esto es gracias a Magical Record. Obtener las notas del almacén de datos es tan simple como llamar a findAll en la clase Note . El método devuelve una matriz de registros como cabría esperar. No olvide importar el archivo de encabezado de la clase Note en la parte superior del archivo de implementación del controlador de vista principal.
1 |
|
2 |
- (void)fetchNotes { |
3 |
// Fetch Notes
|
4 |
self.notes = [NSMutableArray arrayWithArray:[Note findAll]]; |
5 |
}
|
La clasificación de los registros es fácil y elegante. Olvídese de los descriptores de clasificación y eche un vistazo a la implementación actualizada del método fetchNotes acontinuación.
1 |
|
2 |
- (void)fetchNotes { |
3 |
// Fetch Notes
|
4 |
self.notes = [NSMutableArray arrayWithArray:[Note findAllSortedBy:@"date" ascending:YES]]; |
5 |
}
|
El método editNotes: es sencillo. Todo lo que hacemos es cambiar el estilo de edición de la vista de tabla. Eso debería ser suficiente por ahora.
1 |
|
2 |
- (void)editNotes:(id)sender { |
3 |
[self.tableView setEditing:![self.tableView isEditing] animated:YES]; |
4 |
}
|
El método addNote: permanece en blanco por el momento.
1 |
|
2 |
- (void)addNote:(id)sender { |
3 |
|
4 |
}
|
Antes de construir y ejecutar su aplicación, necesitamos implementar los métodos requeridos del protocolo de fuente de datos de vista de tabla. Si está familiarizado con el desarrollo de iOS, esto no debería ser demasiado difícil. Eche un vistazo a las implementaciones de los diversos métodos a continuación para obtener una aclaración.
1 |
|
2 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
3 |
return [self.notes count]; |
4 |
}
|
1 |
|
2 |
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
static NSString *CellIdentifier = @"Cell"; |
4 |
|
5 |
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
6 |
|
7 |
if (cell == nil) { |
8 |
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; |
9 |
|
10 |
// Configure Cell
|
11 |
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; |
12 |
}
|
13 |
|
14 |
// Fetch Note
|
15 |
Note *note = [self.notes objectAtIndex:[indexPath row]]; |
16 |
|
17 |
// Configure Cell
|
18 |
[cell.textLabel setText:[note title]]; |
19 |
[cell.detailTextLabel setText:[note keywords]]; |
20 |
|
21 |
return cell; |
22 |
}
|
1 |
|
2 |
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
return YES; |
4 |
}
|
1 |
|
2 |
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
if (editingStyle == UITableViewCellEditingStyleDelete) { |
4 |
|
5 |
}
|
6 |
}
|
1 |
|
2 |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
[tableView deselectRowAtIndexPath:indexPath animated:YES]; |
4 |
}
|
Compila y ejecuta tu aplicación.
Paso 6: Creando Notas
Cuando el usuario toca el botón Agregar, debería aparecer una vista modal que le permita agregar una nueva nota al almacén de datos. Cree una nueva subclase UIViewController y asígnele el nombre MTEditNoteViewController . Como su nombre lo indica, también usaremos este controlador de vista para editar notas.


Antes de dirigirse al archivo XIB del controlador de vista, agregue tres salidas al archivo de encabezado del controlador de vista. Los dos primeros puntos de venta son instancias de UITextField para el título y las palabras clave de la nota. La tercera salida es una instancia de UITextView para el cuerpo de la nota.
1 |
|
2 |
#import <UIKit/UIKit.h>
|
3 |
|
4 |
@interface MTEditNoteViewController : UIViewController |
5 |
|
6 |
@property (nonatomic, weak) IBOutlet UITextField *titleField; |
7 |
@property (nonatomic, weak) IBOutlet UITextField *keywordsField; |
8 |
@property (nonatomic, weak) IBOutlet UITextView *bodyView; |
9 |
|
10 |
@end
|
Crear la interfaz de usuario del controlador de vista de edición de notas no debería ser un gran desafío. Agregue dos instancias de UITextField y una instancia de UITextView a la vista del controlador de vista. Configure los campos de texto como desee, por ejemplo, dándoles un texto de marcador de posición. No olvide conectar los puntos de venta del propietario del archivo con los campos de texto y la vista de texto.


Ya que usaremos la clase MTEditNoteViewControllerpara agregar y editar notas, es importante que sepamos en qué estado (agregando o editando) se encuentra el controlador de vista en cualquier momento. Hay varias formas de resolver este problema. Una forma es agregar una propiedad de nota privada al controlador de vista, que es nulo si se crea una nueva nota y se establece durante la inicialización cuando se edita una nota. En situaciones como esta, prefiero trabajar con inicializadores especializados para evitar confusiones y esto es también lo que me permite mantener la propiedad privada de la nota . Además de la propiedad de la nota privada , también agregamos una segunda propiedad privada llamada isEditing , un booleano. La razón de esto se aclarará en unos minutos. Además, no olvide importar el archivo de encabezado de la clase Note .
1 |
|
2 |
#import "MTEditNoteViewController.h"
|
3 |
|
4 |
#import "Note.h"
|
5 |
|
6 |
@interface MTEditNoteViewController () |
7 |
|
8 |
@property (nonatomic, strong) Note *note; |
9 |
@property (nonatomic, assign) BOOL isEditing; |
10 |
|
11 |
@end
|
Vayamos a través de los varios métodos paso a paso. Primero, queremos asegurarnos de que podemos agregar nuevas notas al almacén de datos sin problemas. Comenzamos con el initWithNibName: paquete: método. El único cambio que hacemos es establecer la propiedad isEditing en NO .
1 |
|
2 |
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { |
3 |
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; |
4 |
|
5 |
if (self) { |
6 |
// Set Flag
|
7 |
self.isEditing = NO; |
8 |
}
|
9 |
|
10 |
return self; |
11 |
}
|
Como vimos anteriormente, en el método viewDidLoad , configuramos la vista invocando un método setupView en el que creamos los botones cancelar y guardar. Tenga en cuenta que solo creamos el botón de cancelación si la propiedad de la nota es igual a cero . La razón es que presentamos el controlador de vista de manera modal cuando agregamos nuevas notas, pero presionamos el controlador de vista en una pila de navegación cuando editamos una nota. Si la propiedad de la nota no es igual a cero , también rellenamos los campos de texto y la vista de texto con el contenido de la propiedad de la nota .
1 |
|
2 |
- (void)viewDidLoad { |
3 |
[super viewDidLoad]; |
4 |
|
5 |
// Setup View
|
6 |
[self setupView]; |
7 |
}
|
1 |
|
2 |
- (void)setupView { |
3 |
// Create Cancel Button
|
4 |
if (!self.note) { |
5 |
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancel:)]; |
6 |
self.navigationItem.leftBarButtonItem = cancelButton; |
7 |
}
|
8 |
|
9 |
// Create Save Button
|
10 |
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleBordered target:self action:@selector(save:)]; |
11 |
self.navigationItem.rightBarButtonItem = saveButton; |
12 |
|
13 |
if (self.note) { |
14 |
// Populate Form Fields
|
15 |
[self.titleField setText:[self.note title]]; |
16 |
[self.keywordsField setText:[self.note keywords]]; |
17 |
[self.bodyView setText:[self.note body]]; |
18 |
}
|
19 |
}
|
El método de cancelar: no debe contener sorpresas.
1 |
|
2 |
- (void)cancel:(id)sender { |
3 |
// Dismiss View Controller
|
4 |
[self dismissViewControllerAnimated:YES completion:nil]; |
5 |
}
|
El método save: es un poco más detallado, pero tampoco debería ser demasiado difícil. Primero verificamos si la propiedad de nota del controlador de vista está configurada. Si está configurado, entonces sabemos que una nota se está editando, no se crea. Si la propiedad de la nota es igual a cero, entonces sabemos que se debe crear una nueva nota. Descartar el controlador de vista es un poco complicado, ya que debemos descartar el controlador de vista si se presenta de forma modal cuando se creó una nota y sacarlo de la pila de navegación cuando se editó una nota. Esa es la razón por la que creamos la propiedad isEditing .
1 |
|
2 |
- (void)save:(id)sender { |
3 |
if (!self.note) { |
4 |
// Create Note
|
5 |
self.note = [Note createEntity]; |
6 |
|
7 |
// Configure Note
|
8 |
[self.note setDate:[NSDate date]]; |
9 |
}
|
10 |
|
11 |
// Configure Note
|
12 |
[self.note setTitle:[self.titleField text]]; |
13 |
[self.note setKeywords:[self.keywordsField text]]; |
14 |
[self.note setBody:[self.bodyView text]]; |
15 |
|
16 |
// Save Managed Object Context
|
17 |
[[NSManagedObjectContext defaultContext] saveNestedContexts]; |
18 |
|
19 |
if (self.isEditing) { |
20 |
// Pop View Controller from Navigation Stack
|
21 |
[self.navigationController popViewControllerAnimated:YES]; |
22 |
|
23 |
} else { |
24 |
// Dismiss View Controller
|
25 |
[self dismissViewControllerAnimated:YES completion:nil]; |
26 |
}
|
27 |
}
|
Como puede ver, la creación de una nueva nota es otra de una sola línea cuando se usa Magical Record. Rellenamos la nota con el contenido de los campos del formulario y guardamos el contexto del objeto administrado de la nota. Recuperar una referencia al contexto de objeto gestionado es fácil con Magical Record. Todo lo que tenemos que hacer es pedirle a la clase NSManagedObjectContext el contexto predeterminado. Guardar el contexto es idéntico a guardar un contexto sin registro mágico. A pesar de que registramos el error si algo sale mal, esto no es realmente necesario ya que Magical Record registrará cualquier error en la consola para nosotros.
Ahora es el momento de modificar el método addNote: en el controlador de vista principal. No olvide importar el archivo de encabezado de la clase MTEditNoteViewController .
1 |
|
2 |
- (void)addNote:(id)sender { |
3 |
// Initialize Edit Note View Controller
|
4 |
MTEditNoteViewController *vc = [[MTEditNoteViewController alloc] initWithNibName:@"MTEditNoteViewController" bundle:[NSBundle mainBundle]]; |
5 |
|
6 |
// Initialize Navigation Controller
|
7 |
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc]; |
8 |
|
9 |
// Present View Controller
|
10 |
[self.navigationController presentViewController:nc animated:YES completion:nil]; |
11 |
}
|
Cada vez que se agrega una nueva nota al almacén de datos, debemos actualizar la vista de tabla para mostrar los cambios. Para una aplicación de producción, un mejor enfoque sería observar los cambios en el contexto del objeto gestionado. Sin embargo, en esta aplicación de ejemplo, obtenemos las notas del almacén de datos y volvemos a cargar la vista de tabla cada vez que aparece la vista principal (re). Esto es costoso y, por lo tanto, no se recomienda si planea enviar su solicitud a la App Store. Para situaciones como esta, un controlador de resultados es una solución perfecta.
1 |
|
2 |
- (void)viewWillAppear:(BOOL)animated { |
3 |
[super viewWillAppear:animated]; |
4 |
|
5 |
// Fetch Notes
|
6 |
[self fetchNotes]; |
7 |
|
8 |
// Reload Table View
|
9 |
[self.tableView reloadData]; |
10 |
}
|
Paso 7: Actualización de Notas
Actualizar notas es casi tan fácil como agregar notas. Como mencioné anteriormente, crearemos un inicializador especializado para establecer la propiedad de nota del controlador de vista . Actualice el archivo de encabezado de la clase MTEditNoteViewController agregando el nuevo inicializador como se muestra a continuación. No olvide agregar también una declaración de clase hacia adelante para la clase Note al archivo de encabezado.
1 |
|
2 |
#import <UIKit/UIKit.h>
|
3 |
|
4 |
@class Note; |
5 |
|
6 |
@interface MTEditNoteViewController : UIViewController |
7 |
|
8 |
@property (nonatomic, weak) IBOutlet UITextField *titleField; |
9 |
@property (nonatomic, weak) IBOutlet UITextField *keywordsField; |
10 |
@property (nonatomic, weak) IBOutlet UITextView *bodyView; |
11 |
|
12 |
- (id)initWithNote:(Note *)note; |
13 |
|
14 |
@end
|
El inicializador especializado no es realmente especial. Todo lo que hacemos es configurar la nota del controlador de vista y las propiedades de edición de edición como puede ver a continuación.
1 |
|
2 |
- (id)initWithNote:(Note *)note { |
3 |
self = [self initWithNibName:@"MTEditNoteViewController" bundle:[NSBundle mainBundle]]; |
4 |
|
5 |
if (self) { |
6 |
// Set Note
|
7 |
self.note = note; |
8 |
|
9 |
// Set Flag
|
10 |
self.isEditing = YES; |
11 |
}
|
12 |
|
13 |
return self; |
14 |
}
|
Antes de crear y ejecutar la aplicación una vez más, necesitamos actualizar el método tableView: didSelectRowAtIndexPath: del controlador de la vista principal . En este método, obtenemos la nota correcta, inicializamos una instancia de la clase MTEditNoteViewController y colocamos el controlador de vista en la pila de navegación.
1 |
|
2 |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
[tableView deselectRowAtIndexPath:indexPath animated:YES]; |
4 |
|
5 |
// Fetch Note
|
6 |
Note *note = [self.notes objectAtIndex:[indexPath row]]; |
7 |
|
8 |
// Initialize Edit Note View Controller
|
9 |
MTEditNoteViewController *vc = [[MTEditNoteViewController alloc] initWithNote:note]; |
10 |
|
11 |
// Push View Controller onto Navigation Stack
|
12 |
[self.navigationController pushViewController:vc animated:YES]; |
13 |
}
|
Paso 8: Borrar notas
Para eliminar una nota, necesitamos enmendar el método tableView: commitEditingStyle: forRowAtIndexPath : . Recuperamos la nota, la eliminamos del origen de datos y del contexto del objeto gestionado, y actualizamos la vista de tabla. Como puede ver, eliminar un registro o entidad del almacén de datos es tan simple como enviarle un mensaje de deleteEntity .
1 |
|
2 |
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { |
3 |
if (editingStyle == UITableViewCellEditingStyleDelete) { |
4 |
// Fetch Note
|
5 |
Note *note = [self.notes objectAtIndex:[indexPath row]]; |
6 |
|
7 |
// Delete Note from Data Source
|
8 |
[self.notes removeObjectAtIndex:[indexPath row]]; |
9 |
|
10 |
// Delete Entity
|
11 |
[note deleteEntity]; |
12 |
|
13 |
// Update Table View
|
14 |
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; |
15 |
}
|
16 |
}
|
Raspando la superficie
Al construir Registro Mágico, solo hemos arañado la superficie. Quiero enfatizar que Magical Record es una biblioteca robusta, madura y no solo una amalgama de un puñado de categorías útiles. Como les mostré, Magical Record hace que trabajar con Core Data sea mucho más fácil y menos detallado. Las tareas comunes a menudo son de una sola línea. Compare los siguientes fragmentos de código para obtener todas las notas y ordenarlas por fecha. Usando Core Data esto resultaría en el siguiente fragmento de código.
1 |
|
2 |
NSFetchRequest *fr = [[NSFetchRequest alloc] init]; |
3 |
NSEntityDescription *ed = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:[NSManagedObjectContext defaultContext]]; |
4 |
[fr setEntity:ed]; |
5 |
|
6 |
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES]; |
7 |
[fr setSortDescriptors:@[sd]]; |
8 |
|
9 |
NSError *error = nil; |
10 |
NSArray *result = [[NSManagedObjectContext defaultContext] executeFetchRequest:fr error:&error]; |
Sin embargo, al usar Magical Record, esto solo requiere una línea de código.
1 |
|
2 |
NSArray *result = [Note findAllSortedBy:@"date" ascending:YES]; |
Si tuviéramos que agregar la capacidad de buscar en la lista de notas, un enfoque, aunque no es ideal, sería buscar en el almacén de datos todas las notas con un título o palabra clave que contenga la consulta. Usando Magical Record esto resultaría en la siguiente implementación.
1 |
|
2 |
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"title contains[cd] %@", query]; |
3 |
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"keywords contains[cd] %@", query]; |
4 |
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]]; |
5 |
NSArray *result = [Note findAllWithPredicate:predicate]; |
Conclusión
Como dije, Magical Record tiene mucho más que ofrecer que lo que te he mostrado en este tutorial. Desde la versión 2.0, Magical Record puede tratar con contextos anidados y también proporciona soporte para iCloud y operaciones de subprocesos. El objetivo principal de este tutorial es mostrarle que los Datos Básicos no tienen que ser complicados y Saul Mora lo ilustra con Magical Record.



