Core
Data takes advantage of the Objective-C language and its runtime, and
neatly integrates with the Core Foundation framework. The result is an
easy to use framework for managing an object graph that is elegant to
use and incredibly efficient in terms of memory usage.
Every
component of the Core Data framework has a specific purpose and
function. If you try to use Core Data in a way it wasn't designed for,
you will inevitably end up struggling with the framework.
Developers
new to the Core Data framework often confuse it with and expect it to
work as a database. If there's one thing I hope you'll remember from
this series, it is that Core Data isn't a database and you shouldn't
expect it to act like one. It's the Model in
the Model-View-Controller pattern that permeates the iOS SDK.
Core
Data isn't the database of your application nor is it an API for
persisting data to a database. Core Data is a framework that manages an
object graph. It's as simple as that. Core Data can persist that object
graph by writing it to disk, but that is not the primary goal of the
framework.
Core Data Stack:
Above Image from AppCoda:http://www.appcoda.com/introduction-to-core-data/
1. Uses of CoreData?
Grouping, filtering, and organizing data in memory and in the user interface.
Automatic support for storing objects in external data repositories.
Sophisticated
query compilation. Instead of writing SQL, you can create complex
queries by associating an NSPredicate object with a fetch request.
Version tracking and optimistic locking to support automatic multiwriter conflict resolution.
Effective integration with the OS X and iOS tool chains.
Change tracking and built-in management of undo and redo beyond basic text editing.
Automatic
validation of property values. Managed objects extend the standard
key-value coding validation methods to ensure that individual values lie
within acceptable ranges, so that combinations of values make sense.
Schema migration tools that simplify schema changes and allow you to perform efficient in-place schema migration.
2. What is an abstract Entity?
Specify
that an entity is abstract if you will not create any instances of that
entity. You typically make an entity abstract if you have a number of
entities that all represent specializations of (inherit from) a common
entity that should not itself be instantiated. For example, in the
Employee entity you could define Person as an abstract entity and
specify that only concrete subentities (Employee and Customer) can be
instantiated. By marking an entity as abstract in the Entity pane of the
Data Model inspector, you are informing Core Data that it will never be
instantiated directly.
3. What are the properties of an Entity?
Ans:An entity’s properties are its attributes and relationships, including its fetched properties (if it has any)
4. What are Transient attributes?
Ans:
Transient attributes are properties that you define as part of the
model, but which are not saved to the persistent store as part of an
entity instance’s data. Core Data does track changes you make to
transient properties, so they are recorded for undo operations. You use
transient properties for a variety of purposes, including keeping
calculated values and derived values.
5. Can you merge multiple Data Models?
Ans:
Yes, It is possible to have several data model files.
The NSManagedObjectModel class is perfectly capable of merging multiple
data models into one, that is one of the more powerful and advances
features of Core Data.
6. What is meant by reflexive Relationship in core data?
Ans:
The destination entity of a relationship can even be the same as the
source entity. This is known as a reflexive relationship. It's also
possible to have multiple relationships of the same type with different
names. A person, for example, can have a mother and a father. Both
relationships are reflexive with the only difference being the name of
the relationship.
7. How you store image into Coredata Objects?
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ImageTable" inManagedObjectContext:
managedObjectContext
];
NSManagedObject *newImage = [[NSManagedObject alloc]initWithEntity:entity insertIntoManagedObjectContext:managedObjectContext];
/*
Hit a get service to the image data from server or import an image from local Library
and store to NSData Object"
NSData *dataImage = UIImageJPEGRepresentation(image, 0.0);
*/
[
newImage
setValue:dataImage forKey:@"imageEntity"]; // obj refers to NSManagedObject
CoreData Users (or) CoreData Classes (or) CoreData Stack
NSManagedObjectModel:
you
can compare the managed object model to the schema of a database, that
is, it contains information about the models or entities of the object
graph, what attributes they have, and how they relate to one another.
NSManagedObjectContext
The
NSManagedObjectContext object manages a collection of model objects,
instances of the NSManagedObject class. It's perfectly possible to have
multiple managed object contexts. Each managed object context is backed
by a persistent store coordinator.
NSPersistentStoreCoordinator:
It mediates between the persistent store(s) and the managed object context(s) and also takes care of loading and caching data.
While
a managed object model and persistent store coordinator can be shared
across threads, managed object contexts should never be accessed from a
thread different than the one they were created on.
Without Core
Data, you have to write methods to support archiving and unarchiving of
data, to keep track of model objects, and to interact with an undo
manager to support undo. In the Core Data framework, most of this
functionality is provided for you automatically, primarily through the
managed object context.
Managed Object Model
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Core_Data" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
It
is possible to have several data model files. The NSManagedObjectModel
class is perfectly capable of merging multiple data models into one,
that is one of the more powerful and advances features of Core Data.
The
Core Data framework also supports data model versioning as well as
migrations. This ensures that the data stored in the persistent store(s)
doesn't get corrupted.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Core_Data.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
Managed Object Context
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
The
managedObjectContext manages a collection of model objects, instances
of the NSManagedObject class, and keeps a reference to a persistent
store coordinator.
The NSPersistentStoreCoordinator object is the
brain of the Core Data stack of the application. It talks to one or
more persistent stores and makes sure data is saved, loaded, and cached.
The
persistent store coordinator knows about the data model, the schema of
the object graph if you like, through the NSManagedObjectModel object.
The managed object model creates the application's data model from one
or more .momd files, binary representations of the data model.
DataModel:
Entities>Add Entity> Person
Attributes>Optional, Attribute Type, and Default Value.
Relationships>Name, Destination, Inverse,Delete Rule, Type(To-Many, Many-To-Many), Reflexive Relationships
Core Data makes sure, relationships are only loaded when the application needs them
Managed Objects and Fetch Requests:
Managed Objects>an NSManagedObject instance contains the information of a row in a database table.
The reason Core Data uses NSManagedObject instead of NSObject as its base class for modeling records will make more sense
NSEntityDescription
Each NSManagedObject
instance is associated with an instance of NSEntityDescription. The
entity description includes information about the managed object, such
as the entity of the managed object as well its attributes
andrelationships.
NSManagedObjectContext
A managed object is also
linked to an instance of NSManagedObjectContext. The managed object
context to which a managed object belongs, monitors the managed object
for changes.
Saving a Record:
NSEntityDescription
*entityDescription = [NSEntityDescription entityForName:@"Person"
inManagedObjectContext:self.managedObjectContext];
NSManagedObject *newPersonRecord = [[NSManagedObject
alloc]initWithEntity:entityDescription
insertIntoManagedObjectContext:self.managedObjectContext];
Fetching Records:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Unable to execute fetch request.");
NSLog(@"%@, %@", error, error.localizedDescription);
} else {
NSLog(@"%@", result);
}
if (result.count > 0) {
NSManagedObject *person = (NSManagedObject *)[result objectAtIndex:0];
NSLog(@"1 - %@", person);
NSLog(@"%@ %@", [person valueForKey:@"first"], [person valueForKey:@"last"]);
NSLog(@"2 - %@", person);
}
Faulting:
Core
Data tries to keep its memory footprint as low as possible by not fully
initializing the record and one of the strategies it uses to accomplish
this is faulting. When we fetched the records for the entity, Core Data
executes the fetch request, but it will not fully initialize the
managed objects representing the fetched records. Fault is a placeholder
object representing the record. The moment you access an attribute or
relationship of a managed object, the fault is fired, which means that
Core Data changes the fault into a realized managed object.
Updating Records:
NSManagedObject *person = (NSManagedObject *)[result objectAtIndex:0];
[person setValue:@30 forKey:@"age"];
NSError *saveError = nil;
if (![person.managedObjectContext save:&saveError]) {
NSLog(@"Unable to save managed object context.");
NSLog(@"%@, %@", saveError, saveError.localizedDescription);
}
Deleting Records:
NSManagedObject *person = (NSManagedObject *)[result objectAtIndex:0];
[self.managedObjectContext deleteObject:person];
NSError *deleteError = nil;
if (![person.managedObjectContext save:&deleteError]) {
NSLog(@"Unable to save managed object context.");
NSLog(@"%@, %@", deleteError, deleteError.localizedDescription);
}
NSSortDescriptor, NSPredicate
NSFetchedResultsController:
Whenever
a record is inserted, updated, or deleted in a managed object context,
the managed object context posts a notification through notification
center.
NSManagedObjectContextObjectsDidChangeNotification
NSManagedObjectContextWillSaveNotification
NSManagedObjectContextDidSaveNotification
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;
-
(void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type;
-
(void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath
*)newIndexPath;
Comments
Post a Comment
If any of my posts helped you.... or if you feel for any improvement.. you can leave a comment here.. So that, I will try to implement or make corrections for all of us.