NSPredicate issue with type objects - ios

I have an issue with NSPRedicate; it returns nil value. But my ObjectType sees it; maybe problem in predecateFormat?
I have 3 objects and I get it by Type. Source:
typedef NS_ENUM(NSUInteger, ObjectType) {
FirstType,
SecondType,
ThdType,
};
Then I process with CoreData request:
- (NSArray *)objectsByType:(ObjectType)type{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[self objectEntity]];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"self.objectType == %d", type];
[request setPredicate:pred];
NSError *err = nil;
NSArray *objects = [[self managedContext] executeFetchRequest:request error:&err];
if(err){
DLog(#"Failed to fetch objects %#", [err localizedDescription]);
}
return objects;
}
I think problem is here.

Set your type to an NSNumber as that is what is stored in Core Data. #"self.objectType == %#", #(type)

Related

Delete record from core data not working?

I am working with core data, when I deleting record from DB it's not working.
Entity name : Entity
Attributes : id, date, title
- (void) getData {
NSFetchRequest * fetReq = [NSFetchRequest fetchRequestWithEntityName:#"Entity"];
NSError * fetchErrorObj;
NSArray *result = [self.ad.managedObjectContext executeFetchRequest:fetReq error:&fetchErrorObj];
NSLog(#"array count is %lu", result.count);
NSMutableArray *idArr = [[NSMutableArray alloc]init];
NSMutableArray *titleArr = [[NSMutableArray alloc]init];
NSMutableArray *dateArr = [[NSMutableArray alloc]init];
for (int i=0; i<result.count; i++) {
self.storedManagedObj = [result objectAtIndex:i];
[idArr addObject:[self.storedManagedObj valueForKey:#"id"]];
[titleArr addObject:[self.storedManagedObj valueForKey:#"title"]];
[dateArr addObject:[self.storedManagedObj valueForKey:#"date"]];
}
self.idArray = sidArr;
}
To delete record...
- (IBAction)deleteRecord:(UIButton *)sender {
NSNumber *value=[NSNumber numberWithInt:[[self.idArray objectAtIndex:0] intValue]];
NSLog(#"%#", [self.idArray objectAtIndex:0]);
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Entity"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"id == %#", value];
NSLog(#"predicate :%#", predicate);
[request setPredicate:predicate];
NSLog(#"request :%#", request);
NSError *error = nil;
NSArray *result = [self.ad.managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"result: %#", result);
if (!error && result.count > 0) {
for(NSManagedObject *managedObject in result){
NSLog(#"managedObject :%#", managedObject);
[self.ad.managedObjectContext deleteObject:managedObject];
}
//Save context to write to store
[self.ad.managedObjectContext save:nil];
}
}
I am getting result like this
predicate :id == 38
request : (entity: Entity; predicate: (id == 38); sortDescriptors: ((null)); type: NSManagedObjectResultType; )
result :(
)
The error is pretty clear. It states that you need to specify SortDescriptor to your FetchRequest
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Entity"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"<#Sort key#>"
ascending:YES];
request.sortDescriptors = #[sortDescriptor];
OR
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
Read : NSFetchRequest without sort descriptors
EDIT:
As OP isn't concerned about sorting the result in any specific order and the question lacks the description of entity and the only field that I can see in question is id updating my answer to use id in sort descriptor field
[[NSSortDescriptor alloc] initWithKey:#"id" ascending:YES];
EDIT 2:
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Entity"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"id == %#", [self.idArray objectAtIndex:0]];
Issue in the code was :
NSNumber *value=[NSNumber numberWithInt:[[self.idArray objectAtIndex:0] intValue]];
OP was trying to create a NSNumber from an object in self.idArray using intValue which means idArray is a array of String and not NSNumber. That means id is saved as String in core data and not as NSNumber.
In predicate however OP was trying to pass NSNumber to compare with id. Since id is String and passed argument is NSNumber comparison was failing hence was not returning any objects.

Subquery Predicate Core Data

I have two Entity models "Content" and "LessonsContent" with no relationship between them. Both entities have common attribute "contentID" of NSNumber type. I am fetching all contents objects from "Content" entity for given predicate and storing these objects in contents array. I was successful in doing so.
Now, I want to fetch all lessonsContent objects from "LessonsContent" entity whose contentIds are present in contents array.
I am using following code:
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"(contentType == %#)", #"Games"];
NSError * error;
NSFetchRequest * request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([Content class])];
[request setPredicate:predicate];
[request setReturnsObjectsAsFaults:NO];
NSArray *contents = [[DELEGATE managedObjectContext] executeFetchRequest:request error:&error];
if(error){ NSLog(#"Error in fatching data");}
//predicate = [NSPredicate predicateWithFormat:#"Content.contentID IN %#", contents];
predicate = [NSPredicate predicateWithFormat:#"(SUBQUERY(contents, $x, $x.Content.contentID IN %#).#count != 0)",contents];
request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([LessonsContent class])];
[request setPredicate:predicate];
NSArray * mappingArray = [[DELEGATE managedObjectContext] executeFetchRequest:request error:&error];
NSLog(#"mappingArray %#", mappingArray);
But app is crashing. Please suggest appropriate solution.
Thanks in advance.
You have to get an array of contentID's first. Then use IN.
NSArray *contents = [[DELEGATE managedObjectContext] executeFetchRequest:request error:&error];
NSArray * allContentIDs = [contents valueForKey:#"contentID"];
then use the second predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"contentID IN %#", allContentIDs];
[request setPredicate:predicate];
Hope this helps.

CoreData saving object is not successful

I am trying to update int data by using CoreData but I think I am missing some parts before updating the object. Here what I am trying to do to save the int value. Here I want to both save and update only first object value.
- (IBAction)btnYakClicked:(UIButton *)sender
{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Kalorimetre" inManagedObjectContext:context]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSManagedObject* kaloriObject = [results objectAtIndex:0];
NSNumber *valWeek = [NSNumber numberWithInteger:300];
NSNumber *valMonth = [NSNumber numberWithInteger:1000];
[kaloriObject setValue:valWeek forKey:#"thisweek"];
[kaloriObject setValue:valWeek forKey:#"thismonth"];
}
I don't see the line where you're saving it. For example:
NSError *saveError;
if (![context save:&saveError]) {
NSLog(#"Error: %# %#", saveError, [saveError localizedDescription]);
}
It might also be a good idea to limit the fetch request since you're only looking for the first object:
[request setFetchLimit:1];
I would hope that this would improve performance but cannot confirm.

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"]];
}
}

Core data only returning null

I have a number of objects (NSManagedObject Subclass) which 'seem' to be created and saving correctly, however on reloading i can only get null from any of the variables within the objects.
The right number of objects are being saved, but none of the variables.
I've gone through the code several times, and I cant figure out if the problem is on the saving side or the loading side.
Would very much appreciate any thoughts!
Thanks in advance
//Create a route
- (CNSRoute *) createRoute
{
CNSRoute *p = [NSEntityDescription insertNewObjectForEntityForName:#"CNSRoute" inManagedObjectContext:context];
[allRoutes addObject:p];
//NSLog(#"Route: %#", p);
return p;
}
//Load all routes from core data
- (void) loadAllRoutes
{
NSLog(#"All Routes: %#", allRoutes);
if (!allRoutes) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *e = [[model entitiesByName] objectForKey:#"CNSRoute"];
[request setEntity:e];
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sd]];
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
if (!result) {
[NSException raise:#"Fetch Failed" format:#"Reason: %#", [error localizedDescription]];
}
NSLog(#"LOAD RESULT: %#", result);
for (CNSRoute *route in result) {
NSLog(#"Loading Route... %#", [route name]);
}
allRoutes = [[NSMutableArray alloc] init];
[allRoutes setArray:result];
//NSLog(#"%#", allLocations);
}
}
//Save context
- (BOOL)saveChanges
{
NSError *err = nil;
BOOL successful = [context save:&err];
if (!successful) {
NSLog(#"ERROR SAVING: %#", [err localizedDescription]);
}
return successful;
}
//Save when application enters background
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[CNSTravelController sharedStore] saveChanges];
}

Resources