0

I am a beginner and I am trying to move my app to Core Data. I am following the Big Nerd Ranch 3rd Edition book, but in that book they have a store class that holds all its items in an item class. My app is different. I have an task class and the tasks are displayed with task arrays which are declared in the TableView Controller, and if you tap on a task its details come up in a Detail View Controller. The thing is, the book says I need to create an NSManagedObjectContext, NSManagedObjectModel, and an NSPersistentStoreCoordinator, which they do in the store. Where would I declare these in my app? The TableView controller or the Detail View Controller? Here is my code:

Tasks.h

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

@interface Tasks : NSManagedObject

@property (nonatomic) NSDateComponents *conversionInfo;
@property (nonatomic) NSTimeInterval dateCreated;
@property (nonatomic) double orderingValue;
@property (nonatomic, retain) NSString * taskName;
@property (nonatomic) double timeInterval;
@property (nonatomic, retain) NSString * timeIntervalString;
@property (nonatomic, retain) NSManagedObject *assetType;

@end

Tasks.m

@implementation Tasks

@dynamic conversionInfo;
@dynamic dateCreated;
@dynamic orderingValue;
@dynamic taskName;
@dynamic timeInterval;
@dynamic timeIntervalString;
@dynamic assetType;

-(void)awakeFromFetch{
    [super awakeFromFetch];
}
-(void)awakeFromInsert{
    [super awakeFromInsert];
    NSTimeInterval t = [[NSDate date] timeIntervalSinceReferenceDate];
    [self setDateCreated:t];
}
-(NSString *)timeIntervalString{
    NSCalendar *sysCalendar = [NSCalendar currentCalendar];
    NSDate *date = [NSDate date];
    NSDate *date1 = [NSDate dateWithTimeInterval:self.timeInterval sinceDate:date];
    unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit;
    self.conversionInfo = [sysCalendar components:unitFlags fromDate:date  toDate:date1  options:0];
    if ([self.conversionInfo hour] == 0){
        if ([self.conversionInfo minute] == 1) {
            self.timeIntervalString = [NSString stringWithFormat:@"%d MIN", [self.conversionInfo minute]];
        } else {
            self.timeIntervalString = [NSString stringWithFormat:@"%d MINS", [self.conversionInfo minute]];
        }
    } else if ([self.conversionInfo hour] == 1) {
        if ([self.conversionInfo minute] == 0){
            self.timeIntervalString = [NSString stringWithFormat:@"%d HR", [self.conversionInfo hour]];
        } else if ([self.conversionInfo minute] == 1) {
            self.timeIntervalString = [NSString stringWithFormat:@"%d HR %d MIN", [self.conversionInfo hour], [self.conversionInfo minute]];
        } else {
            self.timeIntervalString = [NSString stringWithFormat:@"%d HR %d MINS", [self.conversionInfo hour], [self.conversionInfo minute]];
        }
    } else {
        if ([self.conversionInfo minute] == 0) {
            self.timeIntervalString = [NSString stringWithFormat:@"%d HRS ", [self.conversionInfo hour]];
        } else if ([self.conversionInfo minute] == 1){
            self.timeIntervalString = [NSString stringWithFormat:@"%d HRS %d MIN", [self.conversionInfo hour], [self.conversionInfo minute]];
        } else {
            self.timeIntervalString = [NSString stringWithFormat:@"%d HRS %d MINS", [self.conversionInfo hour], [self.conversionInfo minute]];
        }
    }
    return self.timeIntervalString;
}
@end

TableViewController.m

-(NSMutableArray *)taskArray {
    if (!taskArray) {
        taskArray = [NSMutableArray array];
    }
    return taskArray;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 cellSubclassCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (!cell)
        cell = [[cellSubclassCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];

    if([indexPath section] == 0){
    cell.textLabel.text = [[[self.taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString];

    cell.imageView.image = [UIImage imageNamed:@"unchecked.png"];
        cell.imageView.highlightedImage = [UIImage imageNamed:@"uncheckedhighlighted.png"];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
        cell.textLabel.textColor = baseColor;

        NSString *detailText = [[self.taskArray objectAtIndex:[indexPath row]] timeIntervalString];
        cell.detailTextLabel.text = detailText;
               [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:12]];
        [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:16]];
[cell.contentView setAlpha:1];
    } else if ([indexPath section] == 1) {
    cell.textLabel.text = [[[self.completedArray objectAtIndex:[indexPath row]] taskName] uppercaseString];

     cell.imageView.image = [UIImage imageNamed:@"checked.png"];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
        cell.textLabel.textColor = baseColor;
        NSString *detailText = [[self.completedArray objectAtIndex:[indexPath row]] timeIntervalString];
        cell.detailTextLabel.text = detailText;
        [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:12]];
        [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:16]];
        [cell.contentView setAlpha:0.5];
    }
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)];
    //cell.contentView
    [cell.imageView addGestureRecognizer:tap];
    cell.imageView.userInteractionEnabled = YES;
    return cell;
    }
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    Tasks *task = [[Tasks alloc]init];
    if (indexPath.section == 0){
    task.taskName = [[self.taskArray objectAtIndex:[indexPath row]] taskName];
        task.timeInterval = [[self.taskArray objectAtIndex:[indexPath row]] timeInterval];
    task.dateCreated = [[self.taskArray objectAtIndex:[indexPath row]] dateCreated];
    } else if (indexPath.section == 1){
        task.taskName = [[self.completedArray objectAtIndex:[indexPath row]] taskName];
        task.timeInterval = [[self.completedArray objectAtIndex:[indexPath row]] timeInterval];
        task.dateCreated = [[self.completedArray objectAtIndex:[indexPath row]] dateCreated];
    }
    DetailViewController *dvc = [[DetailViewController alloc]init];
    [dvc setTestTask:task];
    [[self navigationController] pushViewController:dvc animated:YES];
}

Detail View Controller.m

@interface DetailViewController ()

@end
@implementation DetailViewController
@synthesize testTask,timer,timerLabel, date1, alertView, components, timeRemaining;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {


    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [_timeLeft setFont:[UIFont fontWithName:@"BebasNeue" size:25]];
   }
-(IBAction)startTimer:(id)sender{
    [sender setHidden:YES];
    [pauseButton setHidden:NO];
    [continueButton setHidden:NO];
        gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        self.date1 = [NSDate dateWithTimeInterval:[testTask timeInterval] sinceDate:[NSDate date]];

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    [timer fire];

}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [timerLabel setFont:[UIFont fontWithName:@"BebasNeue" size:60]];
    [[self navigationItem] setTitle:[testTask taskName]];
    if (startButton.hidden == NO){
        [pauseButton setHidden:YES];
        [continueButton setHidden:YES];
    } else {
        [pauseButton setHidden:NO];
        [continueButton setHidden:NO];
    }
      timeRemaining = [NSString stringWithFormat:@"%02d:%02d:%02d", [components hour], [components minute], [components second]];
    timerLabel.text = timeRemaining;
    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];

    [testTask setTaskName:[testTask taskName]];
    [testTask setTimeInterval:[testTask timeInterval]];

}
-(void)timerAction:(NSTimer *)t{
     NSDate *now = [NSDate date];
    components = [gregorianCalendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit  fromDate:now toDate:self.date1 options:0];

    timeRemaining = nil;
    if([now compare:self.date1] == NSOrderedAscending){
        timeRemaining = [NSString stringWithFormat:@"%02d:%02d:%02d", [components hour], [components minute], [components second]];
        NSLog(@"works %@", timeRemaining);
    } else {
        timeRemaining = [NSString stringWithFormat:@"00:00:00"];
        [self.timer invalidate];
        self.timer = nil;
        if (self.alertView == NULL){
       self.alertView = [[UIAlertView alloc]initWithTitle:[testTask taskName] message:@"Time is up!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];       
        NSLog(@"ended");
        }
    }
   timerLabel.text = timeRemaining;
    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
    self.alertView = NULL;
}
EvilAegis
  • 733
  • 1
  • 9
  • 18

2 Answers2

0

You should declare NSManagedObjectContext, NSManagedObjectModel, and an NSPersistentStoreCoordinator in your AppDelgate.h file.

All these three objects are mostly required to be allocated menory only once in the application.
You would need NSManagedObjectContext throughout your app to save/ edit/retrieve managed objects.

My suggestion: Create a new project, choose Master- Detail Application template. Check Use Core data option.

You will get all the template code regarding Core Data in the AppDelegate.h and AppDelegate.m file of this new application which you can copy/paste in your application.

Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
  • and I would access them by using [[UIApplication sharedApplication]delegate]? – EvilAegis Jul 24 '13 at 15:10
  • You would want to use NSManagedObjectContext object most of the time in other view controllers and you can see in template codet it is a property in AppDelegate.h. So to get its reference you will have to get the AppDelegate object by using AppDelegarte *appDelegate = [[UIApplication sharedApplication]delegate]; and then where you want NSManagedObjectContext reference simply do, appDelegate.managedObjectContext – Puneet Sharma Jul 24 '13 at 15:18
  • also how would i convert my data source array in the tableview controller to core data? – EvilAegis Jul 24 '13 at 15:56
  • AppDelegate is definitely a class and regarding your data source array of table view controller, you will have to fetch the array items from Core Data. If you are unfamiliar with Core Data I would suggest you to read these Apple Docs: http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html – Puneet Sharma Jul 24 '13 at 17:20
0

They are all created in appDelegate class. When you create the project you select core data option and a model and all NSManagedObjectContext, NSManagedObjectModel, and an NSPersistentStoreCoordinator are created for you. They are global you can access them any where by using:


[[UIApplication sharedApplication]delegate]


Abdullah Shafique
  • 6,878
  • 8
  • 35
  • 70
Shankar BS
  • 8,394
  • 6
  • 41
  • 53