Boolean values and core data - objective-c

I have Boolean values in a entity, the values are all show 0.
The values are fetched and no matter what I always get back a TRUE value.
Here is the code, the problem is probably at the last 2 lines of code.
What am I doing wrong?
-(NSInteger)getStatus:(NSString*)nameID;
{
**//Fetch Request**
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity =
[NSEntityDescription entityForName:#"status"
inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"id_Name = %#", nameID];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
}
**//Values**
status *ENT_status;
ENT_status = [fetchedObjects objectAtIndex:0];
//Either way, both these lines return YES when it would be NO
//------------------------------------------------------------------
BOOL one = ENT_status.status_one;
NSNumber *two = [NSNumber numberWithBool:ENT_status.status_two];

By default, boolean values are represented as NSNumber objects in the managed objects.
So you can either use it as it is:
NSNumber *one = ENT_status.status_one;
or convert it to a plain (scalar) BOOL:
BOOL one = [ENT_status.status_one boolValue];
(In your code, the pointer ENT_status.status_one is always interpreted as YES.)
Alternatively, you can use the option "Use scalar properties for primitive data types"
when creating the managed object subclass in Xcode.

I know its a bit late and probably no one is using Objective-C anymore but i came across this problem and what worked for me was:
to retrieve a boolean value from object:
BOOL myBool = [[myManagedObject valueForKey:#"myKey"] boolValue];
and to set the new value:
myManagedObject.myKey = #YES;

Related

Why can I not get a properly formatted string from NSArray element?

I'm trying to retrieve an attribute from my core data model and put the acquired string into the title of my navigation bar. I must be doing something wrong, as I cannot set my retrieved string as the title, yet I can set the title if I manually enter the string.
Here is how I am retrieving from Core Data:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Area" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
//set predicate
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"identifier == %#", self.area_id];
NSArray *area = [context executeFetchRequest:fetchRequest error:&error];
NSString *area_name = [area valueForKey:#"name"];
NSString *test = #"test";
NSLog(#"%#",test);
NSLog(#"%#",area_name);
When I set the title using self.tabBarController.title = area_name; I get "NSArrayI stringByTrimmingCharactersInSet:]: unrecognized selector sent to instance" and it sets just fine when I set it to the test variable.
I also noticed that the NSLog for the variable test is "test" whereas the NSLog output for area_name is: ( "Single Area" )
Is this because of how I am retrieving my area_name from the array? Should I be using a dictionary instead? Forgive me for my ignorance, I'm fairly new to obj-c.
Thanks.
Here is mistake
NSString *area_name = [area valueForKey:#"name"];
area object is type of NSArray which contains Area objects.
So you need to get element from that array, and then read name.
Area *firstArea = [area firstObject];
NSString *area_name = firstArea.name;
NSLog(#"%#",area_name);
Change the predicate to this:
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"identifier = %#", self.area_id];
I suppose than self.area_id is init correctly.

Invalid operations to binary expression ('id' and 'id')

I have a array fetched from the core data and trying to do some simple calculation but getting errors of Invalid operations to binary expression
pop_cum[i]= (pop_ln_array[i-1] + pop_ln_array[i]);
//getting error at this point of "Invalid operations to binary expression('id' and 'id')
I know we have to change the type of the array values into int but how?
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Input_Details" inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
// Set example predicate and sort orderings...
request.propertiesToFetch = #[ #"pop_Ln" ];
request.resultType = NSDictionaryResultType;
//if you change the sort order here, please change it to SDInputDetailsList also
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"sewer_No" ascending:YES];
[request setSortDescriptors:#[sortDescriptor]];
NSError *error;
NSArray *pop_ln_array = [moc executeFetchRequest:request error:&error];
int arrayCount=[pop_ln_array count];
//Calculating cumulative population, flow & peak factor
NSLog(#"arrayCount is %d",arrayCount);
if (pop_ln_array == nil)
{
NSLog(#"Cumilative population line array is nil");
}
else
{
NSArray *pop_cum[arrayCount];
for(int i=0;i<[pop_ln_array count];i++)
{
NSLog(#"Cumilative array at %d is %#",i,pop_ln_array[i]);
if (i==0)
{
pop_cum[i]=pop_ln_array[i] ;
}
else
{
pop_cum[i]= (pop_cum[i-1] + pop_ln_array[i]); //getting error at this point of "Invalid operations to binary expression('id' and 'id')
}
}
}
Use as follows
for(int i=0;i<[pop_ln_array count];i++){
NSLog(#"Cumilative array at %d is %#",i,pop_ln_array[i]);
if (i==0){
pop_cum[i]=pop_ln_array[i];
NSLog(#"pop_cum[%d] %#",i,pop_cum[i]);
}
else {
NSLog(#"Pop_cum %#",pop_cum[i-1]);
[pop_ln_array[i]intValue]);
NSInteger first=[pop_ln_array[i-1]intValue], second=[pop_ln_array[i]intValue];
NSInteger sum=first+second;
pop_cum[i]=[NSString stringWithFormat:#"%d",sum];
}
}
You are adding two ids. Which can not be.
Convert it to integerValue or intValue or any numerical and then add.

NSPredicate always gives back the same data

I am trying to work with NSPredicates. But it always give me back the same array. Here you can see my predicate.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whichAlbum.album_id == %d", AlbumId];
[request setEntity:[NSEntityDescription entityForName:#"Picture" inManagedObjectContext:self.genkDatabase.managedObjectContext]];
[request setPredicate:predicate];
Also when I try it hardcoded. It gives back the same array.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whichAlbum.album_id == 5"];
My database model is:
And here you can see how I put data in my database for entity Picture.
+ (Picture *)pictureWithGenkInfo:(NSDictionary *)genkInfo
inManagedObjectContext:(NSManagedObjectContext *)context
withAlbumId:(int)albumId
withPictureId:(int)pictureId;
{
Picture *picture = nil;
picture = [NSEntityDescription insertNewObjectForEntityForName:#"Picture"
inManagedObjectContext:context];
picture.url = [genkInfo objectForKey:PICTURES_URL];
picture.pic_album_id = [NSNumber numberWithInt:albumId];
picture.picture_id = [NSNumber numberWithInt:pictureId];
return picture;
}
Anybody can help me ?
Kind regards
EDIT
for (NSDictionary *genkInfo in albums ) {
albumId++;
Album *album = [Album albumWithGenkInfo:genkInfo inManagedObjectContext:document.managedObjectContext withAlbumId:albumId];
for (NSDictionary *genkInfo2 in pictures ) {
pictureId++;
Picture *pic = [Picture pictureWithGenkInfo:genkInfo2 inManagedObjectContext:document.managedObjectContext withAlbumId:albumId withPictureId:pictureId];
[album addPicturesObject:pic]; // this method should be automatically generated
}
pictureId = 0;
// table will automatically update due to NSFetchedResultsController's observing of the NSMOC
}
Better, assuming the value for AlbumId is some kind of number primitive:
old style:
[NSPredicate predicateWithFormat:#"whichAlbum == %#", [NSNumber numberWithInt:AlbumId]];
modern style: (xcode 4.5)
[NSPredicate predicateWithFormat:#"whichAlbum == %#", #(albumId)];
As it looks like predicateWithFormat: might only generate proper predicates with %# and #K in its format strings.
Best: Assuming you have access to the Album managed object you are trying to match try this:
[NSPredicate predicateWithFormat:#"whichAlbum == %#", album];
Match to the object, not one of its properties
just remove whichAlbum and try:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"album_id == %d", AlbumId];

NSPredicate for matching property

What in the world am I doing wrong here? Frustrated beyond belief.
I have an array that contains a certain type of object with a property. We'll just call that property "number". It is of type NSUInteger.
I also have an entity that has an attribute of "number", with a type of Integer 64.
I'm trying to create a fetch request that finds me all the objects in my Core Data store that do not exist in the other array with objects.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:#"EntityName" inManagedObjectContext:context];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"NOT (%#.number IN number)",someArrayWithObjects];
NSError *error = nil;
NSArray *notMatchingObjects = [context executeFetchRequest:fetchRequest error:&error];
This returns a nil array. I know that I have objects with numbers in my local store that do not exist in my other array. Am I doing something wrong?
Use the fact that NSArrays are key-value coding compliant and will give you an array of property values with valueForKey: (For NSUInteger it will wrap them in NSNumbers)
NSArray *predicateInts = [someArrayWithObjects valueForKey:#"number"];
[NSPredicate predicateWithFormat:#"NOT (number IN %#)",predicateInts];
First you have to create an array of NSNumber objects that contains just the numbers that you want to exclude.
Then you can use the following fetch request:
[NSPredicate predicateWithFormat:#"NOT (number IN %#)", arrayWithNumbers];

Number of elements in NSArray where (....)

I am used to working in C# using the linq extensions (list.select(...).where(...) ext), and I was wondering if there was some way of doing the same sort of thing in Objective-C. This would save me from building a number of rather complicated queries using Core Data, which is great for some things, but perhaps not the best for complex queries (or maybe I'm just uninformed).
Is there some kind of equivalent for linq in Objective-C/Core Data?
EDIT: More specifically, I would like to count the number of elements that fit some criteria. Say my model has a field called date. I am trying to select the distinct dates, and then calculate how many of each date there are. In SQL this would be like a group by, and a COUNT aggregate.
Your question goes from very general ("linq equivalent?") to very specific (computing count by date). I'll just answer your specific question.
Unfortunately, NSArray doesn't have a built-in map or select method, but it does offer NSCountedSet, which will compute what you want:
NSCountedSet *dateSet = [NSCountedSet set];
for (id thing in array) {
[dateSet addObject:[thing date]];
}
for (NSDate *date in dateSet) {
NSLog(#"There are %d instances of date %#", [dateSet countForObject:date], date);
}
Change predicate , and "Date" keys with your props
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"child" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:#"Date"]];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"(start <= %# ) and (completion < 100)",sda ];
[fetchRequest setPredicate:predicate];
int c = [self.managedObjectContext countForFetchRequest:fetchRequest error:nil];
Here was something posted with comes close
filtering NSArray into a new NSArray in objective-c
Anyway AFAIK you don't have some sort of linq in Objective-C but you have. Arrays and Blocks. And Blocks are functions. So you can really filter on anything in there.
Of course, Cora Data has many functions to make complex queries:
In example to get sum of elements, you have two major ways:
first - get your data to NSSet or NSArray and use #sum operator:
//assume that `childs` are NSArray of your child entities and ammount is attribute to sum, and has attributes start (date) and completion (integer)
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"child" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"(start <= %# ) and (completion < 100)", dzis];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
NSError *error = nil;
if ([afetchedResultsController performFetch:&error]) {
NSArray *childs = afetchedResultsController.fetchedObjects;
NSNumber *sum=[childs valueForKeyPath:"#sum.ammount"];
}
second is using specific fetch for specific value with added NSExpressionDescription with a sum. This way is harder but better for larger db's
suppose if you have an array of your model objects, you could that with the following statement,
NSArray *distintDatesArray = [array valueForKeyPath:#"#distinctUnionOfObjects.date"];
for ( NSDate *date in distintDatesArray)
{
NSLog (#"Date :%# ,count : %d",date,[[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"date = %#",date]] count]);
}
This will have same effect as the group by query.