Issue with Coredata update - ios

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)
{
...
}

Related

How to delete entries in core data

i am new to core data..
I know how to store and item.
- (void)dbSave:(NSString *)uri withContent:(NSDictionary *)content withExpiry:(double)date {
Cache *cache = [self dbLoad:uri];
if (cache == nil) {
cache = [NSEntityDescription insertNewObjectForEntityForName:#"Cache" inManagedObjectContext:[self managedObjectContext]];
}
double time = (double) [[NSDate date] timeIntervalSince1970] + date;
[cache setLocal:uri];
[cache setTime:#(time)];
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:content forKey:#"data"];
[archiver finishEncoding];
[cache setData:data];
NSError *error;
if (![[self managedObjectContext] save:&error]) {
}
}
But i am stuck with creating a method to clear this core data data base.. Does anyone know how?
NSManagedObjectContext *managedObjectContext=[appDelegate managedObjectContext];
NSFetchRequest *fetchRequest=[NSFetchRequest fetchRequestWithEntityName:#"entity"];
NSArray* currentRecord = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
if (currentRecord.count)
{
for (NSManagedObject *obj in currentRecord)
{
[managedObjectContext deleteObject:obj];
}
NSError * error = nil;
if (![managedObjectContext save:&error])
NSLog(#"Can't save ! %# %#",error,[error localizedDescription]);
else
NSLog(#"Data deleted");
}
use this
NSManagedObjectContext *managedContext = [[APP_DELEGATE dbManagerObj] newPrivateContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Cache"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"isUserData = %#",[NSNumber numberWithBool:true]];
[fetchRequest setPredicate:predicate];
if (IS_IOS9_ANDABOVE) {
NSBatchDeleteRequest *batchDeleteRequest = [[NSBatchDeleteRequest alloc]initWithFetchRequest:fetchRequest];
[[[APP_DELEGATE dbManagerObj]persistentStoreCoordinator]executeRequest:batchDeleteRequest withContext:managedContext error:nil];
}
else
{
NSArray *userRelatedDay = [managedContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *object in userRelatedDay) {
[managedContext deleteObject:object];
}
}

I cannot insert value with NSNumber datatype into my coredata

Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'Unacceptable type of value for
attribute: property = "XXXXX"; desired type = NSNumber; given type =
NSTaggedPointerString; value = 0.'
Tried: [enter image description here][1]
[message setValue:localID forKey:#"local_id"];
localID is of type NSNumber
DataModel image: [1]: https://i.stack.imgur.com/7WTlU.png
[self insertInLocatDB:print_data entityName:#"Message_data" withPredicate:#"receiver_id" filterWith:#"unique_id"];
Using this to insert into CoreData:
-(void)insertInLocatDB :(NSMutableArray *)arr_msg entityName:(NSString*)name withPredicate:(NSString*)predicateText filterWith:(NSString*)filterText
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:name inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id =[self getMaxLocalId:name];
for(int i=0; i<[arr_msg count]; i++)
{
[fetched_data removeAllObjects];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"%# like %# ",predicateText,[[arr_msg objectAtIndex:i]objectForKey:predicateText]];
[request setPredicate:predicate];
NSError *error;
NSArray *matchingData=[app.context executeFetchRequest:request error:&error];
local_id=local_id+1;
for (NSManagedObject *obj in matchingData)
{
[fetched_data addObject:[obj valueForKey:filterText]];
}
NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
if(![fetched_data containsObject:filter])
{
NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
[arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
[arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
for (int i=0;i<[arr_keys count];i++)
{
if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
&& ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
{
[message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
}
}
[arr_keys removeAllObjects];
[arr_values removeAllObjects];
}
}
}
If you have a core data attribute as shown in my screen shot.
Then, the following snippet of code will work for you.
BOOL result;
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
NSManagedObject *newMessage = [NSEntityDescription insertNewObjectForEntityForName:#"message"
inManagedObjectContext:context];
[newMessage setValue:[NSNumber numberWithInt:local_id] forKey:#"local_id"];
[newMovie setValue:movieName forKey:#"message"];
NSError *error = nil;
// Save the object to persistent store
result = YES;
if (![context save:&error]) {
result = NO;
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
return result;
and a function to get the managed object context
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
Edited Code of Sandhya.
-(NSInteger)getMaxLocalId :(NSString*)entitiyName
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:entitiyName inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id = 0;
request.fetchLimit = 1;
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"local_id" ascending:NO]];
NSError *error = nil;
local_id=[[app.context executeFetchRequest:request error:&error].firstObject integerValue];
return local_id;
}
Then used the following to insert in to CoreData
NSInteger local_id =[self getMaxLocalId:name];
local_id=local_id+1;
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
make sure you get the local_id.
As you have NSInteger, For conversion you should use [NSNumber numberWithInteger:] Instead of [NSNumber numberWithInt:]
UPDATE 2 :
NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
if(![fetched_data containsObject:filter])
{
NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
[arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
[arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
for (int i=0;i<[arr_keys count];i++)
{
if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
&& ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
{
if(![[arr_keys objectAtIndex:i] isEqualToString:#"local_id"]){
[message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
}
}
}
[arr_keys removeAllObjects];
[arr_values removeAllObjects];
}
-(NSInteger)getMaxLocalId :(NSString*)entitiyName
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:entitiyName inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id = 0;
request.fetchLimit = 1;
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"local_id" ascending:NO]];
NSError *error = nil;
local_id=[[app.context executeFetchRequest:request error:&error].firstObject integerValue];
return local_id;
}
Then used the following to insert in to CoreData
NSInteger local_id =[self getMaxLocalId:name];
local_id=local_id+1;
[message setValue:myNumber forKey:#"local_id"];

Cannot perform operation without a managed object context

I'm trying add items from core data query to nsmutablearray but I'm getting this error:
"Cannot perform operation without a managed object context"
Here is my code:
NSPredicate *productPredicate = [NSPredicate predicateWithFormat:#"TRUEPREDICATE"];
NSManagedObjectContext *moc = self.managedObjectContext;
NSEntityDescription *description = [ NSEntityDescription entityForName:#"Product" inManagedObjectContext:moc];
NSFetchRequest *request = [NSFetchRequest new];
request.predicate = productPredicate;
request.entity = description;
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
for (NSInteger i = 0; i < results.count; i++)
{
NSString *productName = [[results objectAtIndex:i] valueForKey:#"productName"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"productName == %#", productName];
NSArray *match = [_listOfProducts filteredArrayUsingPredicate:predicate];
if (match == 0)
{
[self.listOfProducts addObject:[results objectAtIndex:i]];
}
}
Where I'm getting the error is at the momento of adding the object to nsmutablearray:
[self.listOfProducts addObject:[results objectAtIndex:i]];
Any of you knows why I'm getting this error?, I'll really appreciate your help.

executeFetchRequest taking too long .

Even though I don't have more than 3 records in my table , and a single table. Method : executeFetchRequest takes too long
loanIDArray=[[NSMutableArray alloc]init];
appDelegate=[[UIApplication sharedApplication] delegate];
context=[appDelegate managedObjectContext];
entityDesc=[NSEntityDescription entityForName:#"Personal_Info" inManagedObjectContext:context];
NSFetchRequest* request=[[NSFetchRequest alloc]init];
[request setEntity:entityDesc];
NSPredicate* predicate=[NSPredicate predicateWithFormat:#"status_of_form==%#",#"Completed"];
[request setPredicate:predicate];
NSError* fetchError;
NSError* error;
This line takes too long
NSArray* objects = [context executeFetchRequest:request error:&fetchError];
if (!fetchError) {
for (NSManagedObject* obj in objects) {
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}
else
NSLog(#"Status Fetch Error : %#",fetchError.description);
[context save:&error];
if (!error)
NSLog(#"count : %d",loanIDArray.count );
else
NSLog(#"error : %#",error.description);
try replace this code:
if (!fetchError) {
for (NSManagedObject* obj in objects) {
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}
with this to avoid iteration:
if (!fetchError) {
loanIDArray = [objects valueForKeyPath:#"app_id"];
}
Try this.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:entityDesc];
NSError *error = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"status_of_form==%#",#"Completed"];
[fetchRequest setPredicate:predicate];
NSArray *request = [context executeFetchRequest:fetchRequest error:&error];
if (!request.count==0) {
for (int i = 0; i<=request.count-1;i++) {
NSManagedObject *obj = [request objectAtIndex:i];
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}

Getting username after authentification with coredata predicate

I am a beginner in Xcode. I would like to get the username or the ID after the user enters their login and password in textfield. I am sure I am doing wrong.
My code bug is after the access granted.
app due to uncaught exception
'`NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]:
object cannot be nil`'
Here is my code:
- (IBAction)stepInButton:(id)sender {
AppDelegate *appDelegateCoreData = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegateCoreData managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Player" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:
#"(playerlogin = %#) AND (playerpassword =%#)", self.loginTextField.text, self.passwordTextField.text];
[request setPredicate:pred];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
self.loginStatusLabel.hidden = NO;
NSLog(#"LOGIN IN ACCESS DENIED");
} else {
NSLog(#"LOGIN IN ACCESS GRANTED");
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:#"playerfirstname"];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setExpression:keyPathExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
// Handle the error.
}
else {
if ([objects count] > 0) {
NSString *playerFirstName = [[objects objectAtIndex:0] valueForKey:#"playerfirstname"];
NSLog(#"PlayerFirstName: %#", [[objects objectAtIndex:0] valueForKey:#"playerfirstname"]);
self.welcomePlayerLabel.text = [NSString stringWithFormat: #"Welcome %#", playerFirstName];
}
}
self.loginStatusLabel.hidden = YES;
self.signButton.hidden = YES;
self.stepButton.hidden =YES;
self.loginStatusLabel.text =(#"Access Granted");
self.loginStatusLabel.textColor = [UIColor greenColor];
self.loginStatusLabel.hidden = NO;
//FirstViewController *firstViewController = [[FirstViewController alloc] init];
//[self.navigationController pushViewController:firstViewController animated:YES];
//[self.navigationController pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"first"] animated:YES];
}
}
ok I got it.
I retieved the playerFirstName directly form object like Dan Shelly said. Thanks you Dan.
- (IBAction)stepInButton:(id)sender {
AppDelegate *appDelegateCoreData = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegateCoreData managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Player" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:
#"(playerlogin = %#) AND (playerpassword =%#)", self.loginTextField.text, self.passwordTextField.text];
[request setPredicate:pred];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
self.loginStatusLabel.hidden = NO;
NSLog(#"LOGIN IN ACCESS DENIED");
} else {
NSLog(#"LOGIN IN ACCESS GRANTED");
NSString *playerFirstName = [[objects objectAtIndex:0] valueForKey:#"playerfirstname"];
self.welcomePlayerLabel.text = [NSString stringWithFormat: #"Welcome %#", playerFirstName];
self.loginStatusLabel.hidden = YES;
self.signButton.hidden = YES;
self.stepButton.hidden =YES;
self.loginStatusLabel.text =(#"Access Granted");
self.loginStatusLabel.textColor = [UIColor greenColor];
self.loginStatusLabel.hidden = NO;
}
}

Resources