articles

Home / DeveloperSection / Articles / Core data and how to use it in iOS Objective C

Core data and how to use it in iOS Objective C

Allen Scott 17241 07-Jan-2017

Core Data is a framework that you use to manage the model layer objects in your application. It is also a persistent technology, in that it can persist the state of the model objects to disk but the important point is that Core Data is much more than just a framework to load and save data. Lazy loading of objects , and copy-on-write data sharing to reduce overhead. It is Sophisticated query compilation. Without writing SQL  queries, you can create complex queries by using an NSPredicate object with a fetch request.  

Core Data in iOS Objective- C 

Create new project  select empty project or single view application  or whatever your requirement  click on next button  display the following screen –


Core data and how to use it in iOS Objective C


enter product name what you want in my case name is 'CoreDataSample' and check Use Core Data check box and click on next button. If you want to use  core data in existing project you can include  core data model using File->New->File open the following dialog click Next


Core data and how to use it in iOS Objective C


after adding it to project select CoreDataSample.xcdatmodeld it look like the following screen-


Core data and how to use it in iOS Objective C


you can add Entity on click on Add Entity (red marked)  .You can add attributes using + sign marked as blue and remove attributes using – sign marked as green. Now create your desired entity with their attributes. In AppDelegate.h  add the following lines if not in your appdelegate.h file  if you will create new project and select core data xcode will create it automatically in you AppDelegate.h file. My AppDelegate.h file is -


#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
 
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
@end
 
AppDelegate.m  
 
#import "AppDelegate.h"
 
@implementation AppDelegate
 
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    returnYES;
}
 
- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
 
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
 
- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
 
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
 
- (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.
    [selfsaveContext];
}
 
 
#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.mindstick.CoreDataSample" in the application's documents directory.
    return [[[NSFileManagerdefaultManager] URLsForDirectory:NSDocumentDirectoryinDomains: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 = [[NSBundlemainBundle] URLForResource:@"CoreDataSample"withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModelalloc] 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 = [[NSPersistentStoreCoordinatoralloc] initWithManagedObjectModel:[selfmanagedObjectModel]];
    NSURL *storeURL = [[selfapplicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataSample.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinatoraddPersistentStoreWithType:NSSQLiteStoreTypeconfiguration:nilURL:storeURL options:nilerror:&error]) {
        // Report any error we got.
        NSMutableDictionary *dict = [NSMutableDictionarydictionary];
        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]);
        abort();
    }
   
    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]);
            abort();
        }
    }
}
 
@end


Now create another UIViewController add employee as shown in the screen shot- add three textfield named as Name,Email Id,Contact Number .

 Core data and how to use it in iOS Objective C


Add button on navigation bar search and Add New and create IBAction for buttons and IBOutlet for textfields. My DetailViewController.h and  DetailViewController.m code is -

 

//
//  DetailViewController.h
//  CoreDataSample
 
#import <UIKit/UIKit.h>
#include "AppDelegate.h"
#import <CoreData/CoreData.h>
@interface DetailViewController : UIViewController
 
@property (strong, nonatomic) id detailItem;
@property (weak, nonatomic) IBOutlet UITextField *txtName;
@property (weak, nonatomic) IBOutlet UITextField *txtEmail;
@property (weak, nonatomic) IBOutlet UITextField *txtContactNo;
@property(weak,nonatomic)AppDelegate *appDelegate;
- (IBAction)AddPerson:(id)sender;
 
@end
 
 
//
//  DetailViewController.m
//  CoreDataSample
//
 
 
#import "DetailViewController.h"
#import "Employee+CoreDataProperties.h"
 
@interface DetailViewController ()
 
@end
 
@implementation DetailViewController
 
#pragma mark - Managing the detail item
 
- (void)setDetailItem:(id)newDetailItem {
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;
           
        // Update the view.
       
    }
}
 
 
 
- (void)viewDidLoad {
    [super viewDidLoad];
      _appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    // Do any additional setup after loading the view, typically from a nib.
 
   
   
}
 
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
 
- (IBAction)AddPerson:(id)sender {
 
    Employee* item = [NSEntityDescription insertNewObjectForEntityForName:@"Employee"
                                               inManagedObjectContext:_appDelegate.managedObjectContext];
    item.name=_txtName.text;
    item.email = _txtEmail.text;
    item.contactNo = _txtContactNo.text;
    [_appDelegate saveContext];
    _txtName.text=@"";
    _txtEmail.text=@"";
    _txtContactNo.text=@"";
}
 
@end


Now you can add employee info using core data .Let us display saved data in my table view controller . Create UITableViewController  with a prototype cell with identifier Cell and create a segue from  DetailViewController to EmployeeTableViewController  for Search button on navigation bar. I am attaching screen shot of Employee view in UITableView-


Core data and how to use it in iOS Objective C

Here is source code of  my  EmployeeTableView.h and EmployeeTableView.m   code is as-

//
//  EmployeeTableView.h
//  CoreDataSample
//
 
 
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "Employee.h"
 
@interface EmployeeTableView : UITableViewController
@property (weak, nonatomic) IBOutlet UITableViewCell *ReuseCell;
@property (retain,nonatomic) NSFetchedResultsController * fetchedResultsController;
@property (retain,nonatomic) NSMutableArray * employeeCollection;
@property(retain,nonatomic)AppDelegate *appDelegate;
@end
 
 
//
//  EmployeeTableView.m
//  CoreDataSample
 
#import "EmployeeTableView.h"
 
@implementation EmployeeTableView
@synthesize fetchedResultsController;
@synthesize employeeCollection;
- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.delegate=self;
    self.tableView.dataSource=self;
     _appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
   
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Employee"];
    self.employeeCollection = [[_appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
    NSLog(@"count=%ld", (unsigned long)self.employeeCollection.count);
   // [self.tableView reloadData];
   
}
 
#pragma mark - Table View
 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.employeeCollection.count;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                      reuseIdentifier:@"Cell"];
       
    }
    Employee  *item = [self.employeeCollection objectAtIndex:indexPath.row];
    [cell.textLabel setText:item.name];
    [cell.detailTextLabel setText:item.contactNo];
   
    return cell;
}
 
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_appDelegate.managedObjectContext deleteObject:[self.employeeCollection objectAtIndex:indexPath.row]];
        [self.employeeCollection removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
      
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}
 
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:YES];
     [_appDelegate saveContext];
}
@end


Note- Do not forget to create NSManagedObject Subclass.Select your CoreDataSample.xcdatamodeld and go to Editer-> Create  NSManagedObject Subclass. 


Core data and how to use it in iOS Objective C

and following is the Employee class code -

//  Employee+CoreDataProperties.h
//  CoreDataSample
//
//
//  Choose "Create NSManagedObject Subclass…" from the Core Data editor menu
//  to delete and recreate this implementation file for your updated model.
//
 
#import "Employee.h"
 
NS_ASSUME_NONNULL_BEGIN
 
@interface Employee (CoreDataProperties)
 
@property (nonatomic) int64_t id;
@property (nullable, nonatomic, retain) NSString *name;
@property (nullable, nonatomic, retain) NSString *email;
@property (nullable, nonatomic, retain) NSString *contactNo;
@property (nonatomic) NSTimeInterval creationDate;
@property (nonatomic) NSTimeInterval modificationDate;
 
@end
 
NS_ASSUME_NONNULL_END
 
 
//
//  Employee+CoreDataProperties.m
//  CoreDataSample
//
//  Choose "Create NSManagedObject Subclass…" from the Core Data editor menu
//  to delete and recreate this implementation file for your updated model.
//
 
#import "Employee+CoreDataProperties.h"
 
@implementation Employee (CoreDataProperties)
 
@dynamic id;
@dynamic name;
@dynamic email;
@dynamic contactNo;
@dynamic creationDate;
@dynamic modificationDate;
 
@end
 
 //
//  Employee.h
//  CoreDataSample
//
//
 
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
 
NS_ASSUME_NONNULL_BEGIN
 
@interface Employee : NSManagedObject
 
// Insert code here to declare functionality of your managed object subclass
 
@end
 
NS_ASSUME_NONNULL_END
 
#import "Employee+CoreDataProperties.h"
 
 
 
//
//  Employee.m
//  CoreDataSample
//
 
#import "Employee.h"
 
@implementation Employee
 
// Insert code here to add functionality to your managed object subclass
 
@end

Leave Comment

Comments

Liked By