Detecting duplicate entries in core data and removing them - objective-c

I have started to work on a core data project. The data to store in the database comes from the server and I am able to store it successfully into coredata. However, each fetch is resulting in duplicate entries. What is the best way to check whether the data exists in core data and append only if the data is not found.
Here is my implementation so far:
for (NSDictionary *dict in array) {
DatabaseManagement *mo = [NSEntityDescription insertNewObjectForEntityForName:#"Subscription" inManagedObjectContext:context];
[mo setValuesForKeysWithDictionary:dict];
The array contains nested dictionary with keys corresponding to my entities attribute names.
I know I can use NSPredicate to achieve this but can someone provide sample code or some resources?

Related

NSPredicate with "NOT IN" condition fails

Ok, here's my problem. I am synchronizing data from a server via a REST-api. The returned data is in JSON, I loop through it and takes appropriate actions depending on the data. That is, I either store it as a new object, updates the object if it already exists or deletes it if only exists locally.
To achieve this, I collect the IDs from the returned objects when I loop through the JSON. This gives me a index of all the returned objects. I then query my locally stored data to see if it contains any objects that should be deleted (in other words, if the local ID does exists or not in the JSON response).
And here's my issue (sorry for a somewhat lengthy prologue); the NSPredicate that I use only works for certain scenarios and which ones work or fails seems to be random.
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// Array which populates with the IDs from the server
NSMutableArray *arrayOfLogIDS = [[NSMutableArray alloc] init];
/*
Fetching and parsing JSON ... collecting IDs and adding them to the array. See example below;
*/
NSArray *logs = [[json valueForKey:#"Logs"] valueForKey:#"Object"];
// Looping through the logs array
for (NSArray *log in logs) {
[arrayOfLogIDS addObject:[log valueForKey:#"serverID"]];
}
// The NSPredicate
NSPredicate *serverIDS = [NSPredicate predicateWithFormat:#"NOT (serverID IN %#)", arrayOfLogIDS];
// The array which holds the objects that should be deleted
NSArray *logs = [Logs MR_findAllWithPredicate:serverIDS inContext:localContext];
}];
The problem is just that the NSPredicate won't work for this specific circumstance. It returns no results even though I know I have objects locally that should be deleted.
I use this approach in other places in the application, and it works as expected. As you can see I am using Magical Record for Core Data management in this app.
I feel that I have completely run out of things to try next, so any help would be much appreciated! :)
Ok, as it turns out, the array of IDs sometimes had the values stored as string and sometimes as integers. Integers worked well with NSPredicate, strings not so much :) Solved! Thanks all for your time.

What is the best way to reference a core data entity?

I have been reading and working a lot with core data recently, and I love the way it implements the data storage.
However, there is one thing I am still not able to resolve in my app.
On my data model, I have an entity which represents a chunk of text the user have inserted in a text field. I want to be able to give the user the possibility to embed this chuck of text into another text field by referencing it.
If I was working with a database directly, I would do something like this:
The user adds a chunk of text to the database. It happens to have the row index 17.
The user goes back to the main editor where it can reference chunks of text from the database and inserts a pattern such as {chunk.17} where 17 is the row index in the database.
The user clicks a "parse" button, making the app query the database for this row and replace the string {chunk.17} for the text chunk stored in there.
Since Core Data has no such thing as an auto incremented index, I am not sure how to create a similar behavior without much work. Any ideas are appreciated!
It sounds like you'll need to add a property (such as "id") to your entity that has some unique value (there are lots of discussions on Stackoverflow about how to generate a unique ID/value for an object). Once you have that, you can reference this value using an NSPredicate:
NSFetchRequest *req = [[NSFetchRequest alloc] initWithEntityName:#"Demo"];
// A predicate is used as a limited substitute for a 'where' clause. In this case, we're specifying that
// the result set should only contain entities whose id is 'chunk.17'.
[req setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE[c] %#", #"id", #"chunk.17"]];
NSError *error;
NSArray *results = [self.managedObjectContext executeFetchRequest:req error:&error];

Retrieve Specific Object from Core Data

I'm new to Core Data and wondering if it is possible to get an object based on it's attributes, more specifically, an uniqueID I assigned to it. I'm trying to do this because I'm interfacing with a web server, which provides data that will updated the Core Data. I want to search through each of the web server objects, check the timestamp, and if it's different, retrieve that object from core data, and update. I've looked at using existingObjectWithId but it seems like I would have to know which object I'm searching for, or the ID of that object. I've also thought about sorting the data in both arrays, and then checking each simultaneously, but didn't think that is viable.
Here is what I'm doing so far:
-(NSMutableArray*) updateRootBeers:(NSMutableArray*)webRootBeerList{
NSManagedObjectContext* moc = [self managedObjectContext];
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc]initWithEntityName:#"Rootbeer"];
coreDataRootBeerList = [[moc executeFetchRequest:fetchRequest error:nil]mutableCopy];
//check to see if core data has data, if not, call function to populate the list
if (coreDataRootBeerList.count <=0) {
[self addRootBeerToCoreData:webRootBeerList];
}else{
//otherwise I want to update the core data object if object data is different.
for(RootBeer* currentRootBeer in webRootBeerList){
RootBeer* mRootBeer = [moc existingObjectWithId:currentRootBeer error:nil];
}
}
}
I've also thought about using nested for loops to check for the data in each array, but that seems like poor coding.
Any help or thoughts would be great.
You want to make an NSFetchRequest. You can set the entity and provide a Predicate. Really simple and clean.

Check if a specific data is into core data

Here's the question. I have a table where I save some data, which I get from a NSArray of NSDictionaries which will have the properties to be saved. Each dictionary in the array is a separated entity, so I loop the dictionary and save it using insertNewObjectForEntityForName to create diferent entity.
I need to refesh the data, but when is saving the data is duplicating the data that exist already in coredata. Im trying to check if the id exist on the core data using
for(NSDictionary *exist in dic){
if([[campaignDictionary objectForKey:#"element"] isEqualToString:#"id"]){
idToCheck = [dic objectForKey:#"value"];
}
}
if(table.campaign_id == idToCheck){
return exist = YES;
}
but its leaving the rest of the data without being checked, so only the id not being duplicated, any ideas to how approach this? thanks!
I decided it was best to delete all my content from Coredata before inserting the new content, thanks!!

NSFetchedResultsController add Objects manually

I recently stumbled across a difficult problem..
I'm normally using a NSFetchedResultsController to get Data out of my CoreData, and display it within a TableViewController.
The problem I have now is that I can't get the results I want with a NSFetchRequest right away, because having a m:n relationship and I implemented a Table in Core Data (References) which stores the references to the Objects...
So what I do now is, I use a fetch Request:
NSArray* references = [self.context executeFetchRequest:fetchRequest error:&error];
and then iterate through this array to get my Objects:
for(References* ref in references)
{
Post* tmp = ref.ref_of_post;
}
So is there a way to manually add these objects to my NSFetchedResultsController or is there a possibility to get the wanted object trough a NSFetchRequest?
Thanks for your help.
Never mind that.
I just added these Objects to a NSMutableArray and then would use this Array in the same way as the NSFetchedResultsController..