📜 ⬆️ ⬇️

Use ActiveRecord to work with Core Data

Introduction


Active Record is a design pattern for applications that use a database to store information. The database table is displayed as an application class, and the class object is a table row. The interface of such an object must contain such functions as Insert, Update and Delete, plus properties that correspond to the columns of the table. When an object is created, a new row is added to the table, when an object is updated, the corresponding row in the table is also updated.

Core Data and Active Record

')
Core Data is based on the Active Record pattern, but to work with the database you have to write quite cumbersome code. For example, here is an example of Apple :

NSManagedObjectContext *moc = [self managedObjectContext]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc]; NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; [request setEntity:entityDescription]; // Set example predicate and sort orderings... NSNumber *minimumSalary = ...; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary]; [request setPredicate:predicate]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; NSError *error; NSArray *array = [moc executeFetchRequest:request error:&error]; if (array == nil) { // Deal with error... } 


As you can see from the example for searching the Employee database in which the last name contains “Worsley” and the salary is higher than the minimum salary, you have to write a lot of “extra” code.

The solution to this problem was provided by Magical Panda in its ActiveRecord for Core Data library.

Here is the same example, only using ActiveRecord for Core Data:
 NSNumber *minimumSalary = ...; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary]; NSArray *employees = [Employee findAllSortedBy:@"firstName" asceding:YES withPredicate:predicate]; 


ActiveRecord for Core Data allows you to:

1. Make Cleaner Code for Working with Core Data
2. Allows you to do simple single-line queries.
3. Despite its simplicity, it allows you to modify NSFetchRequest when the query needs modification.

Using ActiveRecord for Core Data


Customization


Download the ActiveRecord for Core Data library and add it to the project:



Add to MyProjectName-Prefix.pch #import "CoreData+ActiveRecordFetching.h"

in AppDelegate in application: didFinishLaunchingWithOptions: adding a call
[ActiveRecordHelpers setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"MyProject.sqlite"];
This method will create an NSPersistentStore with the specified name and a model file .xcdatamodeld that it will find in the application bundle.

Default Managed Object Context


When working with Core Data, an NSManagedObjectContext object is used. ActiveRecord for Core Data allows you to set the DefaultContext, which will be the default NSManagedObjectContext for the entire application. Creating an NSManagedObjectContext for use in other threads is as follows:

NSManagedObjectContext *myNewContext = [NSManagedObjectContext newContext];

This context can be made by default, and then it will be used in all requests if the name of the request method does not end with “inContext:”. It is recommended to create and set the default context only in the main thread.

Data retrieval


Suppose there is a Song class with the id, length, and name fields:

@interface Song : NSManagedObject
@property (nonatomic, retain) NSNumber * length;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * id;
@end

#import "Song.h"

@implementation Song
@dynamic length;
@dynamic name;
@dynamic id;
@end


The ActiveRecord for Core Data library contains the category “NSManagedObject + ActiveRecord.h”, that is, all the heirs of NSManagedObject will respond to ActiveRecord for Core Data messages.
Most of the methods in ActiveRecord for Core Data return an array of results. For example, if you need to find all Song objects in the database, the call will look like this:

NSArray *songs = [Song findAll];

Search for songs sorted by name will be:

NSArray *songsSorted = [Song findAllSortedByProperty:@"name" ascending:YES];

If there is a song with a unique attribute value, then you can use the function:

Song *song = [Song findFirstByAttribute:@"name" withValue:@"Imagine"];

Also ActiveRecord for Core Data allows you to use NSPredicate:

NSPredicate * songFilter = [NSPredicate predicateWithFormat: @ "length>% @", ...];

NSArray *songs = [Song findAllWithPredicate:peopleFilter];

Data editing


Creating an entry in the database using ActiveRecord for Core Data is very simple:

Song *song = [Song createEntity];

Uninstall:

[song deleteEntity];

Editing attributes:

Song *song = [Song createEntity];
song.name = "stairway to heaven";
song.length = [NSNumber numberWithInt:150];


After editing the data, you must save the context:

[[NSManagedObjectContext defaultContext] save];

Source: https://habr.com/ru/post/130262/


All Articles