Search code examples
iosobjective-cuitableviewcore-datansmanagedobjectcontext

How to Enter Unique Data In to Core Data Value?


i am Newbie in iOS Development. i want to Show only Single Value in Core Data Table for Duplicate Data Array. i know that this question are asked many times i search fro it but i not get the Solution. Please Help me for that.

i create an app that Contain One View in One View i make an HMSegmentedControll and in HMSegmentedControll i add 10 Segmented Controls and each Segmented Controls Contain UITableView i want to Make When User Select any UITableViewCell then its Data also Stored in Core Data, it is Working fine but Always it Add Same data i want to Stop Duplication of this same Data Array. Please Give me Solution For this

Here my Code for UITableViewCell Selection Method.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (self.bookMark)
{
    [self.bookMark setValue:cell.headLabel.text forKey:@"title"];
    [self.bookMark setValue:cell.categoryLabel.text forKey:@"category"];
    [self.bookMark setValue:cell.timeLabel.text forKey:@"post_date"];
    [self.bookMark setValue:image forKey:@"imagelink"];
    [self.bookMark setValue:post_id forKey:@"post_id"];
    [self.bookMark setValue:self.shortDiscription forKey:@"shortdescription"];
}
else
{
     newBookMark = [NSEntityDescription insertNewObjectForEntityForName:@"BookMark" inManagedObjectContext:context];
    [newBookMark setValue:cell.headLabel.text forKey:@"title"];
    [newBookMark setValue:cell.categoryLabel.text forKey:@"category"];
    [newBookMark setValue:cell.timeLabel.text forKey:@"post_date"];
    [newBookMark setValue:image forKey:@"imagelink"];
    [newBookMark setValue:post_id forKey:@"post_id"];
    [newBookMark setValue:self.shortDiscription forKey:@"shortdescription"];
}
NSError *error = nil;
if (![context save:&error])
{
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
}

And Here self.bookMark and newBookMark both are NSManagedObject.

And i Code for Fetch a Request as

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription  entityForName:@"BookMark" inManagedObjectContext:managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
NSError *error;
self.allreadArray = [managedObjectContext executeFetchRequest:request error:&error];

And i set Here Dictionary to fetch data like as

NSDictionary *entityProperties = [entity propertiesByName];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"post_id"]]];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"title"]]];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"shortdescription"]]];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"post_date"]]];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"category"]]];
[request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"imagelink"]]];

and here i show Fetch Data in tableview cell as

-(CustumCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=@"Cell";
CustumCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    NSArray *nib=[[NSBundle mainBundle]loadNibNamed:@"CustumCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}
[cell.spinner startAnimating];
[cell.headLabel setHighlightedTextColor:[UIColor grayColor]];
cell.viewLabel.hidden=TRUE;
NSManagedObject *device = [self.allreadArray objectAtIndex:indexPath.section];
NSString  *image=[device valueForKey:@"imagelink"];
if([image isKindOfClass:[NSString class]])
{
    [cell.cellImage sd_setImageWithURL:[NSURL URLWithString:[image stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:@"Setting.png"] options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
     {
         [cell.spinner stopAnimating];
         cell.spinner.hidesWhenStopped=YES;
     }];
}
cell.headLabel.text=[device valueForKey:@"title"];
cell.categoryLabel.text=[device valueForKey:@"category"];
cell.timeLabel.text=[device valueForKey:@"post_date"];
return cell;
}

then it is Always Fetch @"imagelink" data i want to Fetch All Data Please Give me Solution for that thanks in Advance.


Solution

  • There are a number of places where your problem could lie. I'll list them all, in the hope that one of them is of some help:

    First, in your cellForRowAtIndexPath method, you have:

    NSManagedObject *device = [self.allreadArray objectAtIndex:indexPath.section];
    

    Hence you are using the section number to determine which device you use to populate the cell. This will be the same device for every cell in the section. It may be that is deliberate (you might want several sections with a single cell in each, rather than one section). But you might instead mean to use the row number to determine which device to use, so that every row is different. If so, replace the above line with:

    NSManagedObject *device = [self.allreadArray objectAtIndex:indexPath.row];
    

    Secondly, in the didSelectRowAtIndexPath method, you save the attribute values either to self.bookMark (if it exists) or to a newly created Bookmark object. But you do not set self.bookMark anywhere. Hence, every time you select a row, you create a new object. If you actually want self.bookMark to refer to that newly created bookmark object, then add:

    self.bookMark = newBookMark;
    

    to the didSelectRowAtIndexPath method, immediately after you create newBookMark. Hence the next time you select a row, self.bookMark will exist and you will save the new values to it, rather than creating another (duplicate) object.

    Thirdly, your fetch is using setReturnsDistinctResults. It is unusual to use this, though it might be what you need. But are you using that option just to overcome the problem of having duplicate objects in your database? To use an example, suppose you have four objects with the following attributes:

    title    post_id    category    imageLink
    Red      0001       Primary     pic1.jpg
    Blue     0002       Primary     pic2.jpg
    Green    0003       Secondary   pic1.jpg
    Red      0004       Secondary   pic2.jpg
    

    If you use setReturnsDistinctResults with setPropertiesToFetch set to imageLink, then the results will include only two items:

    imageLink
    pic1.jpg
    pic2.jpg
    

    With setPropertiesToFetch set to both imageLink and category, then your results will include four items:

    category    imageLink
    Primary     pic1.jpg
    Primary     pic2.jpg
    Secondary   pic1.jpg
    Secondary   pic2.jpg
    

    If you actually want to know the distinct values for each attribute, then you must run the fetch several times, and change the propertiesToFetch each time:

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];
    [request setResultType:NSDictionaryResultType];
    [request setReturnsDistinctResults:YES];
    NSError *error;
    NSDictionary *entityProperties = [entity propertiesByName];
    [request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"post_id"]]];
    self.postIdArray = [managedObjectContext executeFetchRequest:request error:&error];
    [request setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"title"]]];
    self.titleArray = [managedObjectContext executeFetchRequest:request error:&error];
    etc, etc.
    

    That will result in two arrays, postIdArray having four items:

    post_id
    0001
    0002
    0003
    0004
    

    and titleArray having three items:

    title
    Red
    Blue
    Green
    

    Which of these best describes what you want to obtain in your fetch?

    Sorry for a long answer. Let me know if any of this is helpful or irrelevant, and I will add to or amend the answer accordingly.