While fetching Data through core data, automatically inserting the existing rows again

146 Views Asked by At

I am new to core data. I am trying to implement it in the object oriented way. As a sample project, I created a View Controller which shows data from an sqlite database through core data and the data is entered by another viewController. However, I wanted to handle the data fetching and inserting through a model class, "ContextHandler" and I created another model class "Device" which is a subclass of NSManagedObject.

However, when fetching data, I am re-entering the previously entered data.

Here is my storyboards- enter image description here

My entity model class is named "Device".

Device.h -

#import <CoreData/CoreData.h>

@interface Device : NSManagedObject

@property(nonatomic, strong) NSString *name;
@property(nonatomic, strong) NSString *company;
@property(nonatomic, strong) NSString *version;

@end

and Device.m -

#import "Device.h"

@implementation Device

@dynamic name;
@dynamic company;
@dynamic version;

@end

Through the following class, I am inserting and fetching the device object.

The insertion method is

-(void)addDeviceWithName:(NSString*)name andCompany:(NSString*)company andVersion:(NSString*)version{

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Device" inManagedObjectContext:self.context];

    Device *newDevice = [[Device alloc] initWithEntity:entity insertIntoManagedObjectContext:self.context];
    newDevice.name = name;
    newDevice.company = company;
    newDevice.version = version;

    NSError *error = nil;

    if(![self.context save:&error]){
        NSLog(@"Could not add due to %@ %@", error, [error localizedDescription]);
    }
}

and the fetching method is -

-(NSMutableArray*)getDeviceListFromDatabase{
     NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Device"];
    NSMutableArray *devices = [[self.context executeFetchRequest:fetchRequest error:nil] mutableCopy];

    NSMutableArray *deviceList =[[NSMutableArray alloc]initWithCapacity:[devices count]];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Device" inManagedObjectContext:self.context];

    for(NSManagedObject *currentDevice in devices){
       //here I am inserting the data again
        Device *deviceObject = [[Device alloc] initWithEntity:entity insertIntoManagedObjectContext:self.context];

        deviceObject.name = [currentDevice valueForKey:@"name"];
        deviceObject.company = [currentDevice valueForKey:@"company"];
        deviceObject.version = [currentDevice valueForKey:@"version"];

        [deviceList addObject:deviceObject];
    }
    return deviceList;
}

The thing is while I initialise the device object, I end up adding the object to database again.

How to solve this issue. How to initialise the Device class without inserting the data again.

I could not do -

Device *deviceObject = [[Device alloc] init];

If I do that, the app crashes. Can anyone please help me out here.

2

There are 2 best solutions below

1
On

You don't need this bit

//here I am inserting the data again
Device *deviceObject = [[Device alloc] initWithEntity:entity insertIntoManagedObjectContext:self.context];

because that really is inserting new objects into the Managed Object Context

Your data will be returned in the array of deviceList as Device

0
On

This should fix your problem:

-(NSArray *)getDeviceListFromDatabase {
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Device" inManagedObjectContext:self.context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];

    NSError *error;
    NSArray *array = [self.context executeFetchRequest:request error:&error];
    // Error handling.
    return array; // This is your array of Device objects
}

The fetch returns objects of your type Device when you specified this in your model.

Note that the return type is a normal array an not a NSMutableArray.