Analysis of [IOS] core data I — enabling core data


Core data is a very important way of data persistence in IOS. Fmdb, which has been used to store data before, seldom uses core data. However, it is necessary to understand the data persistence method on this large scale
Due to the limited understanding of the author, please correct the incorrect place, thank you!

Before we start, let’s take a look at these objects

This is the data model of the application. This model includes entity, property, fetch request, etc

Participate in the whole process of various operations on data objects, and detect the changes of data objects to provide support for undo / redo and update the UI bound to data
data record
Data entity object
It mainly deals with the reading and writing operations of the underlying data. Generally, we don’t need to contact him;
In addition: the. Xcdatamodeld file is compiled as. Momd or. Mom file

1、 Create a new project and enable core data

If you want to use core data, you need to check it when creating a new project (of course, you can also create it manually), that is, check use core data in the interface of entering project name, as shown in the following figure:

Analysis of [IOS] core data I -- enabling core data

For such a new project, Xcode will help us add some content related to core data. You will find that in the list on the left of the project, there is a file with xcdatamodeld as the suffix. This is our data model file

Analysis of [IOS] core data I -- enabling core data

This is generated by default. Of course, we can also add it manually, just like creating other files: right click > new file… And select core data > Data Model on the left

Analysis of [IOS] core data I -- enabling core data

Next, enter the name and create!
The difference between the project with core data not checked is that in appdelegate, the. H file contains the following contents:

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;


In the. M file, the implementation of related methods is added, which can be seen at the bottom of the file!

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application terminates.
    [self saveContext];

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *)applicationDocumentsDirectory {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "com.artup.LZCoreData" in the application's documents directory.
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

- (NSManagedObjectModel *)managedObjectModel {
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"LZCoreData" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    // Create the coordinator and store
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"LZCoreData.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // Report any error we got.
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    return _persistentStoreCoordinator;

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;

#pragma mark - Core Data Saving support

- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

2、 Visual operation of adding data model

choice LZCoreData.xcdatamodeld File, in which all visual operations are performed;

1. Add an entity

Click the + button below and enter the name of the entity you want to create. Here is the peopleentity

Analysis of [IOS] core data I -- enabling core data

2. Add an attribute

Attributes are mainly displayed in the attributes column in the middle. Click the + at the bottom left to add a new attribute, enter a name, and select a type. Here, define a name attribute of string type:

Analysis of [IOS] core data I -- enabling core data

Note: the first letter of the attribute name must be lowercase, otherwise the following prompt will appear:

Analysis of [IOS] core data I -- enabling core data

There is a special data type here: transformable, which corresponds to the ID type in OC;
In the same way, add the age and sex attributes;
Then, add an entity manentity, and set the attributes as follows:

Analysis of [IOS] core data I -- enabling core data

3. Build connections

For example, the link between peopleentity and manentity has been established,
Select the peopleentity entity, click + in the relationships column in the middle, add a connection, give a name, and select manentity: in destination

Analysis of [IOS] core data I -- enabling core data

The function here is equivalent to adding an attribute of type manentity and name manrelationship to the entity peopleentity;
Apple officials suggest that after establishing a target relationship, we should establish a return relationship, that is, establish a link with peopleentity in manentity;

Analysis of [IOS] core data I -- enabling core data

After selecting a contact, you can set some properties of the contact on the right side:

Analysis of [IOS] core data I -- enabling core data

For example, delete rule, type and so on;
In this way, our data model is established, and the next thing is how to use it

3、 Using data models

The next operation is to write the code. Come to our viewcontroller. M file and import the appdelegate. H header file. We need to use some content about core data in it. Create a new method test1 and add the following code:

//Get proxy
    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    //Get context
    NSManagedObjectContext *context = [delegate managedObjectContext];
    //Get peopleentity entity
    NSManagedObject *people = [NSEntityDescription insertNewObjectForEntityForName:@"PeopleEntity" inManagedObjectContext:context];
    //Set property content
    [people setValue: @ "Liuhuo Fei Tong" forkey: @ "name"];
    [people setValue:@26 forKey:@"age"];
    [people setValue:@0 forKey:@"sex"];
    //Get manentit entity
    NSManagedObject *man = [NSEntityDescription insertNewObjectForEntityForName:@"ManEntity" inManagedObjectContext:context];
    [man setValue:@178.0 forKey:@"height"];
    [man setValue:@60.0 forKey:@"weight"];
    [man setValue: @ "Zhang San" forkey: @ "name"];
    [man setValue:people forKey:@"peopleRelationship"];
    [people setValue:man forKey:@"manRelationship"];
    NSError *error;
    //Save changes
    if ([context save:&error]) {
        Nslog (@ "saved successfully");
    } else {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    //Query entity
    //Create a query request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    //Gets the entity to query
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"PeopleEntity" inManagedObjectContext:context];
    //Add to query request
    [fetchRequest setEntity:entity];
    //Start the query and get the results
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    Nslog (@ "output query results");
    for (NSManagedObject *info in fetchedObjects) {
        NSLog(@"Name: %@", [info valueForKey:@"name"]);
        NSLog(@"age: %@", [info valueForKey:@"age"]);
        NSLog(@"sex: %@", [info valueForKey:@"sex"]);
        NSManagedObject *man1 = [info valueForKey:@"manRelationship"];
        NSLog(@"Name: %@", [man1 valueForKey:@"name"]);
        NSLog(@"weight: %@", [man1 valueForKey:@"weight"]);
        NSLog(@"height: %@", [man1 valueForKey:@"height"]);

I simply added comments to the code, just to test whether the created data model is available;
Therefore, you just use the method of adding data and querying data, and then run the program. You can see the following output on the console:

2016-05-26 15:37:25.496 lzcoredata [5654:567413] saved successfully
2016-05-26 15:37:25.497 lzcoredata [5654:567413] output query results
2016-05-26 15:37:25.498 lzcoredata [5654:567413] name: Liu Huo Fei Tong
2016-05-26 15:37:25.498 LZCoreData[5654:567413] age: 26
2016-05-26 15:37:25.498 LZCoreData[5654:567413] sex: 0
2016-05-26 15:37:25.498 LZCoreData[5654:567413] -----------------------------------
2016-05-26 15:37:25.498 lzcoredata [5654:567413] name: Zhang San
2016-05-26 15:37:25.499 LZCoreData[5654:567413] weight: 60
2016-05-26 15:37:25.499 LZCoreData[5654:567413] height: 178
2016-05-26 15:37:25.501 LZCoreData[5654:567413] ==========================================

It means that we have successfully saved the data and found it out
You may find that I use KVC mode when setting property values and values, which is quite inconvenient. Can I use the form of. To assign values like other models? The answer is yes