I am fetching or querying all the entries from my database (core-data) at three different times in my code, which I find to be an inefficient approach to writing the code.
The method _walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
helps getting all the entries from the database in the form of NSArray
.
I call _walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
for the first time in the viewDidLoad
method, so that I can get all the entries when I launch my app.
Next, I call _walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
when I click on the add button, which invokes the (IBAction)addAction:(id)sender
method, so that my entry gets updated in the TableViewCells
.
Lastly, I call _walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
in the (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
method, in order to update the row count, so that the row count remains inline with the entries in database event after I delete my entries.
Please let me know how I can avoid fetching all the entries three times. Also let me know if I have not followed good practice in this code.
#import "ViewController.h"
#import "DatabaseManager.h"
#import "Walks.h"
@interface ViewController ()
@property (strong,nonatomic) NSArray *walks;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
@synthesize tableView = _tableView;
@synthesize walks = _walks;
-(void)viewDidAppear:(BOOL)animated{
[[DatabaseManager sharedDatabaseManager] simpleAddaDog];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
_walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)addAction:(id)sender {
[[DatabaseManager sharedDatabaseManager]addWalk:[NSDate date]];
_walks = [[DatabaseManager sharedDatabaseManager] getAllWalks];
[self.tableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
_walks = [[DatabaseManager sharedDatabaseManager]getAllWalks];
return _walks.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSString *dateString = [NSDateFormatter localizedStringFromDate:[_walks[indexPath.row] date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
NSLog(@"dateString = %@",dateString);
cell.textLabel.text = dateString;
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return TRUE;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[_tableView beginUpdates];
if(editingStyle == UITableViewCellEditingStyleDelete){
Walks *walkToRemove = _walks[indexPath.row];
[[DatabaseManager sharedDatabaseManager]deleteTheWalks:walkToRemove];
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[_tableView endUpdates];
}
}
@end
Core-data stack:
//
// DatabaseManager.m
// DogWalk
//
// Created by Nilesh Agrawal on 11/9/14.
// Copyright (c) 2014 Nilesh Agrawal. All rights reserved.
//
#import "DatabaseManager.h"
#import "Dog.h"
#import "MyConstants.h"
static DatabaseManager *_sharedInstance;
@implementation DatabaseManager
@synthesize persistantStore =_persistantStore;
@synthesize managedContext = _managedContext;
@synthesize managedObject =_managedObject;
@synthesize managedObjectModel =_managedObjectModel;
+(DatabaseManager *)sharedDatabaseManager{
@synchronized(self){
if(_sharedInstance==nil){
_sharedInstance = [[DatabaseManager alloc] init];
}
}
return _sharedInstance;
}
-(id)init{
if(self = [super init]){
}
return self;
}
-(NSURL *)applicationDocumentsDirectory{
/*
to get the location of the persistant store.
*/
return [[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]lastObject];
}
-(NSManagedObjectModel *)managedObjectModel{
//checkif the managedObjectModel is null otherwise create a new one.
if(_managedObjectModel !=nil){
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@"DogWalk" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
-(NSPersistentStoreCoordinator*)persistantStoreCoordinator{
//first check if the persistant store is nil or not, if not nill then return that one.
NSPersistentStoreCoordinator *persistantStoreCoordinator=nil;
//if the persistant store is nill, then create a new one.
//Adding the managedObejct Model to the persistant store.
persistantStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"DogWalk.sqlite"];
NSError *err=nil;
//Adding the store to the persistant store co-ordinator.
if(![persistantStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&err]){
//in case if error occurs.
NSLog(@"Error,=%@ErrorInfo= %@",err.description,err.userInfo);
}
return persistantStoreCoordinator;
}
-(NSManagedObjectContext *)managedObjectContext{
if(_managedContext!=nil){
return _managedContext;
}
NSPersistentStoreCoordinator *persistantStoreCoordinator = [self persistantStoreCoordinator];
if(persistantStoreCoordinator==nil){
return nil;
}
_managedContext = [[NSManagedObjectContext alloc]init];
[_managedContext setPersistentStoreCoordinator:persistantStoreCoordinator];
return _managedContext;
}
-(void)simpleAddaDog{
NSManagedObjectContext *context = [self managedObjectContext];
NSString *dogName = @"Tommy";
Dog *dog =[NSEntityDescription insertNewObjectForEntityForName:@"Dog" inManagedObjectContext:context];
dog.name = dogName;
[context save:nil];
}
-(void)addWalk:(NSDate *)date{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchedRequest = [[NSFetchRequest alloc] init];
/*
fetch the first dog and then add walks to it .
*/
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Dog" inManagedObjectContext:context];
[fetchedRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchedRequest error:nil];
Dog *dog = fetchedObjects[0];
Walks *walk = [NSEntityDescription insertNewObjectForEntityForName:@"Walks" inManagedObjectContext:context];
walk.date = date;
NSMutableOrderedSet *walks = [dog.walks mutableCopy];
[walks addObject:walk];
dog.walks = walks.copy;
[context save:nil];
}
-(NSArray *)getAllWalks{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Dog" inManagedObjectContext:context];
[fetchRequest setEntity:entityDescription];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];
if((long)fetchedObjects.count < 0){
return nil;
}
NSArray *dogArray = [[NSArray alloc] init];
if((long)fetchedObjects.count>0){
Dog *dog = fetchedObjects[0];
NSFetchRequest *fetchRequestDog = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescriptionDog = [NSEntityDescription entityForName:@"Walks" inManagedObjectContext:context];
[fetchRequestDog setEntity:entityDescriptionDog];
fetchRequestDog.predicate = [NSPredicate predicateWithFormat:@"dog==%@",dog];
dogArray = [context executeFetchRequest:fetchRequestDog error:nil];
NSLog(@"dog name = %@, dog Array Count = %ld",dog.name, dogArray.count);
}
return dogArray;
}
-(void)deleteTheWalks:(Walks *)WalkToRemove{
NSManagedObjectContext *managedContext =[self managedContext];
[managedContext deleteObject:WalkToRemove];
[managedContext save:nil];
}
@end