I am having a problem with updating the core data.
i am downloading the data in the background thread comparing with the identifier in core data and count but am having trouble to update now i want to check the identifier present in Core data with JSON Response and if id is present in the JSON Response leave it and if not present in JSON Response (That means That record has been removed in Server side)
Here in this code am checking id is present in core data or not and now i want to check the id is present in json or not to update the records
Any help will be great appreciate thanks in advance
please check the code how am storing the data in to core data
for (int i = 0; i < [arrayData count]; i++) {
NSNumber * idNum = [arrayData objectAtIndex:i][#"id"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Deal"];
[request setPredicate:[NSPredicate predicateWithFormat:#"identifier == %#",idNum]];
[request setFetchLimit:1];
NSUInteger count = [_managedObjectContext countForFetchRequest:request error:&error];
if (count == NSNotFound) {
NSLog(#"ERROR");
}else if (count == 0) {
Deal * dealsEntity = [NSEntityDescription insertNewObjectForEntityForName:#"Deal" inManagedObjectContext:_managedObjectContext];
NSString * name = [arrayData objectAtIndex:i][#"name"];
dealsEntity.nameAttribute = name;
dealsEntity.identifier = idNum;
[appDelegate saveContext];
}
[self performSelectorOnMainThread:#selector(updateData:) withObject:_myArray waitUntilDone:YES];
}
- (void) updateData:(NSArray *)yourData {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Deal" inManagedObjectContext:_managedObjectContext];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setEntity:entity];
NSError *error;
yourData = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
self.myArray = yourData;
[listTableView reloadData];
}
I have tried this with updating or deleting the records from coredata
for (int d = 0; d < [_myArray count]; d++) {
Deal * deal = (Deal*)_myArray[d];
NSNumber * identifier = [deal identifier];
if ([identifier isEqualToNumber:[[arrayData objectAtIndex:d] valueForKey:#"id"]] ) {
NSLog(#"equal %d",d);
} else {
NSLog(#"Kill it ");
}
}
but here the problem is Coredata has 115 records when checking with json but json will have only 114 records and it returns crash
As you have the identifier into your database you just need to change your code little bit
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Deal" inManagedObjectContext:moc]];
[request setPredicate:[NSPredicate predicateWithFormat:#"identifier == %#",idNum]];
[request setFetchLimit:1];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
// check the count
if([results count] == 1) {
// Update your coredata object
} else {
// Create new object
}
Related
How to convert dictionary data to NSManagedObject data?
I used propertiesToFetch, and it returns dictionary data. But I want NSManagedObject data.
please guide me
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:catalogID, pageID, nil]];
[fetch setResultType:NSDictionaryResultType];
[fetch setReturnsDistinctResults : YES];
NSError* error = nil;
self.resultPageArray = [context executeFetchRequest:fetch error:&error];
When I changed the type to NSManagedObjectResultType, then I got non-distinct data. I read that while using propertiesToFetch it saves the data in dictionary format. But I want to get the distinct data and save it into the NSManagedObjects
Try This,
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:catalogID, pageID, nil]];
[fetch setResultType:NSManagedObjectResultType];
[fetch setReturnsDistinctResults : YES];
NSError* error = nil;
self.resultPageArray = [context executeFetchRequest:fetch error:&error];
My code :
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"BookInfo"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPropertiesToFetch:#[catalogID, pageID]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat:#"(bookId == %#)",strId]];
NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if( fetchedItems.count > 0 ) {
BookInfo *bInfo = [fetchedItems lastObject];
NSLog(#"%#",bInfo.bookName);
}
I have solved the issue. I was fetching the data of NSManagedObjects. After that I saved that data to the other array without repetition. And return the new array.
self.resultPageArray = [context executeFetchRequest:fetch error:&error];
NSMutableArray *resultantFinalArr = [[NSMutableArray alloc] init];
for (int i = 0; i<resultPageArray.count; i++)
{
catalogPageDataModel *atIndexI = [resultPageArray objectAtIndex:i];
BOOL find = NO;
for (catalogPageDataModel* catalogPageDataModel in resultantFinalArr)
{
if (catalogPageDataModel.pageid.intValue == atIndexI.pageid.intValue)
{
find = YES;
break;
}
}
if (!find)
[resultantFinalArr addObject:atIndexI];
}
NSLog(#"result array count %lu",(unsigned long)resultantFinalArr.count);
NSLog (#"names: %#",resultantFinalArr);
return resultantFinalArr;
I have a method that is called in the app delegate by the UIViewControllers which deletes the core object that matches the selected objects name. It deletes from the UIListView which is correct and the refresh method (which checks core data for all objects)doesn't bring it back to the list view. However, when I close the application and restart it it brings back the just deleted objects. Here is the method:
-(void)deleteObject:(NSString *)configName
{
//Generates the request context for core data
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"StoredSetups" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(config_name = %#)", configName];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects.count == 0)
{
NSLog(#"No Matches");
}
else
{
matches = objects[0];
[context deleteObject:matches];
}
}
Any help or feed back will be greatly appreciated. Thanks in advance!
you have to save the context after delete like this :
if (objects.count == 0)
{
NSLog(#"No Matches");
}
else
{
matches = objects[0];
[context deleteObject:matches];
[context save:&error];
}
I'm trying to update certain currency abbreviations in the coredata with this function.
- (void)updateCurrencies
{
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:managedObjectContext]];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"Number of data : %lu", (unsigned long)[results count]);
for (int i = 0; i < [results count]; i++) {
Transaction* t = [results objectAtIndex:0];
NSLog(#"currency: %#", t.currency);
if ([t.currency isEqualToString:#"CAN"]) {
t.currency = #"CAD";
NSLog(#"new currency set.");
}
[self saveContext];
}
}
}
I call this function in didFinishLaunchingWithOptions. Now, the log does inform me that t.currency has been updated to CAD. However when I retrieve the data again in HomeViewController and log the currency, it is back to CAN. This is the code in HomeViewController,
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *transaction = [NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:_managedObjectContext];
[request setEntity:transaction];
request.predicate = [NSPredicate predicateWithFormat:#"transactionToUser = %#", [self.content objectAtIndex:i]];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"postdate" ascending:NO];
NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];
[request setSortDescriptors:descriptors];
NSError *error = nil;
NSMutableArray *mutableResult = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableResult == nil) {
//handle error
}
for (int k = 0; k < [mutableResult count]; k++) {
Transaction *t = [mutableResult objectAtIndex:k];
NSLog(#"currency xx: %#", t.currency);
}
What am I doing wrong? Any help is appreciated. Thanks.
Fixed it with a different for loop.
for (Transaction *t in results)
{
...
}
I have an array friendsArray of dictionary objects which looks something like this:
(
{
name = "james p";
phone = 345345345;
},
{
name = "sam b";
phone = 345345345;
},
{
name = "aaron s";
phone = 346346456;
}
)
Now I'm storing it to coredata like this
NSMutableDictionary *friends = [[NSMutableDictionary alloc] init];
for (int count = 0; count <[friendsArray count]; count++) {
NSError *error;
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"FriendContacts" inManagedObjectContext:context];
NSManagedObject *friendsObject = [[NSManagedObject alloc] initWithEntity:entityDesc insertIntoManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
friends = [friendsArray objectAtIndex:count];
[friendsObject setValue:[friends objectForKey:#"name"] forKey:#"name"];
[friendsObject setValue:[friends objectForKey:#"phone"] forKey:#"phone"];
[context save:&error];
}
Here is the screenshot of SQL Browser
It is storing data but making duplicate of this dictionary, I don't know why.
Try the following - its a bit cleaner :)
Observe how many times the log statement is outputted and check the object it outputs.
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"FriendContacts" inManagedObjectContext:context];
for (NSDictionary *friend in friendsArray) {
NSManagedObject *friendsObject = [[NSManagedObject alloc] initWithEntity:entityDesc insertIntoManagedObjectContext:context];
[friendsObject setValue:[friend objectForKey:#"name"] forKey:#"name"];
[friendsObject setValue:[friend objectForKey:#"phone"] forKey:#"phone"];
NSLog(#"Created new friends object: %#", friendsObject);
if ([context hasChanges]) {
NSError *error;
if (![context save:&error]) {
NSLog(#"Problem saving changes: %#", error);
}
}
}
EDIT:
You might also be better off saving after the loop is finished too (if you have a large data set), just move the if statement outside the loop.
I have two methods,
In first method, I do save values in Core Data, while in other, I simply fetch them.
After inserting, when I fetch data in same method, it shows value, but when I try to fetch in other method if returns me null.
My saving Method is
-(void) saveloginData:(NSString *)facebookTok username:(NSString *)userName password:(NSString*)password flag:(NSString *)flag {
NSError *error;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"SignIn" inManagedObjectContext:context]];
[fetchRequest setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSString *facebookTokenData = facebookTok;
NSString *usernameData = userName;
NSString *passwordData = password;
NSString *flagData = flag;
NSLog(#"Facebook Token%#\nUsername%#\npassword%#\nflat%#\n",facebookTokenData,usernameData,passwordData,flagData);
SignIn *signIn = [NSEntityDescription
insertNewObjectForEntityForName:#"SignIn"
inManagedObjectContext:context];
signIn.facebookToken = facebookTokenData;
signIn.username = usernameData;
signIn.password = passwordData;
signIn.flag = flagData;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SignIn"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedArray = [context executeFetchRequest:fetchRequest error:&error];
for (SignIn *info in fetchedArray) {
\\ THis executes and shows values, proves that value are inserted.
NSLog(#"Name ~~~~ : %#", info.username);
NSLog(#"Password ~~~~~~~~ :%#", info.password);
NSLog(#"FLAG ~~~~~~~~~~~ %#",info.flag);
NSLog(#"Facebook Token %#", info.facebookToken);
}
}
My retrieve Method is
-(NSArray*) getLoginData {
NSError *error;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SignIn"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedData = [[NSArray alloc] init];
fetchedData = [context executeFetchRequest:fetchRequest error:&error];
NSLog(#"The count of Array %d", [fetchedData count]); \\ HERE COUNT IS ZERO, WHY?
for (SignIn *info in fetchedData) {
NSLog(#" FF Name ~~~~ : %#", info.username);
NSLog(#"Password ~~~~~~~~ :%#", info.password);
NSLog(#"FLAG ~~~~~~~~~~~ %#",info.flag);
NSLog(#"Facebook Token %#", info.facebookToken);
}
return fetchedData;
}
Please guide that where I am doing mistake.
Your problem is that you need to save conext to get the entity it later.
NSManagedObjectContext save: Attempts to commit unsaved changes to registered objects to their persistent store.
- (BOOL)save:(NSError **)error
Parameters: error: A pointer to an NSError object. You do not need to create an NSError object. The save operation aborts after the first failure if you pass NULL.
Return Value YES if the save succeeds, otherwise NO.
So you need to save context after you modify your object:
signIn.facebookToken = facebookTokenData;
signIn.username = usernameData;
signIn.password = passwordData;
signIn.flag = flagData;
[context save:NULL]; // NULL if you don't need to handle error