Core Data, Get Sum Of Certain Boolean Value Attribute - ios

I'm logging a Core Data attribute "passed" (Boolean value)
for (Circuit *object in self.distributionBoard.circuits) {
NSLog(#"Core Data Value = %d", object.passed);
}
This logs fine. What's the most efficient way to count the number of times the saved boolean value == 1?
Using NSFetchReques or NSExpression did not yield the desired result so far. Looked here: Core Data sum of all instances attribute and similar, with the usual searches

Since your property is a boolean, you can make it a lot simpler than the methods described in that answer. Use a predicate to match the value of passed and then get the count of the result instead of the fetched objects. Something like:
NSFetchRequest<Event *> *fetchRequest = MyEntity.fetchRequest;
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"passed = true"];
NSError *error = nil;
NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error];
Then count has the number of instances where passed is true.

Related

Fetch Realm objects that contain parameter

I have a realm database filled with Restaurant objects that have a url parameter. I'd like to fetch the objects where the url contains what the user has typed in a UITextField.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"url CONTAINS '%#'", self.searchQuery];
RLMResults<Database *> *results = [Database objectsWithPredicate:pred];
if ([results count] == 0) {
NSLog(#"results count == 0");
return nil;
}
Now, when I run this, I always get 0 results. Eventhough I have two example entries that have 'http://www.testingthis.com' as an url and the search query is 'testingthis'. Any ideas as to why I'm not getting results?
You need to perform your search query against the Restaurant class itself; not Database. Realm uses the class you specify to determine which table in which to apply the query.
As an aside, you can also inline NSPredicate queries with +[RLMObject objectsWhere:], so it's not necessary to create a separate NSPredicate object (unless you've got a specific reason). :)
RLMResults *restaurants = [Restaurant objectsWhere:#"url CONTAINS '%#'", #"testingthis"];
If you're trying to query for Restaurant objects that aren't in the default Realm, then you can alternatively use +[RLMObject objectsInRealm: where:] to explicitly control which database you're querying.

Using Kii Query Result

I am running a Kii Query that returns the expected number of results. However the results array contains object formatted as follow
"<KiiObject: 0x130471ae0>"
this is the output from
NSLog(#"%#",results);
I am confident that the Query is working correctly as i can add and remove objects from the bucket and the number of results in the array changes according, i just don't know how to take the results and get the corresponding object.
I have gone over everything in the Kii Doc's
link to Kii Docs
The result is to short to be the object id(uuid string) and i can't find any other reference in the docs that makes sense.
You can refer to bellow snippet
NSError *error = nil;
// Build "all" query
KiiQuery *allQuery = [KiiQuery queryWithClause:nil];
// Create an array to store all the results in
NSMutableArray *allResults = [NSMutableArray array];
// Create a placeholder for any paginated queries
KiiQuery *nextQuery;
// Get an array of KiiObjects by querying the bucket
NSArray *results = [bucket executeQuerySynchronous:allQuery
withError:&error
andNext:&nextQuery];
if (error != nil) {
// Error handling
return;
}
//obtain single KiiObject
KiiObject* firstObject = allResults.firstObject; // now you should get all the object properties
NSLog(#"MaxScore : %#",[firstObject getObjectForKey:#"maxScore"]); //i.e to get "maxScore" value
Below is the links for querying KiiObjects.
http://docs.kii.com/en/guides/ios/managing-data/object-storages/querying/

Sorting NSArray, NSComparator block vs. NSSortDescriptor, with null values

I've been using the block based approach to sort an NSArray... However, I'd noticed a sort-related bug so started to investigate.
Background: I'm dealing with an NSArray of EKReminder objects, which have a creationDate property. I want to sort the reminders by descending creationDate (newest reminders, first).
This was my previous code:
// NSArray* fetchedReminders... contents pulled from reminder calendars...
NSArray* sortedArray = [fetchedReminders sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate* first = [(EKReminder*)a creationDate];
NSDate* second = [(EKReminder*)b creationDate];
return [second compare:first];
}];
That code, I believe, is correct. However, I ended up with some reminders in the database that had null as their creation date. This introduced a bug - the resulting sort was incorrect. The null values were neither at the beginning or the end, and it seems that having nulls in the array messed with this comparison approach, as many of the reminders were out of sequence.
NSSortDescriptor
So, I tried swapping out the block-based approach in favour of sortedArrayUsingDescriptors. Here's the current code:
// NSArray* fetchedReminders... contents pulled from reminder calendars...
NSSortDescriptor* sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"creationDate" ascending:NO];
NSArray* sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray* sortedArray = [fetchedReminders sortedArrayUsingDescriptors:sortDescriptors];
This works.
(With the current data, 101 reminders, 6 of them have null creation dates and they're all placed at the end. The other reminders are in the correct sequence).
Questions
First, am I doing anything wrong with the sortedArrayUsingComparator approach?
If not, is it expected that these different approaches handle nulls differently?
In any case, does that make the NSSortDescriptor approach the preferred method, if you can potentially have nulls in your data?
The core issue that you're running into here is that you're not manually handling null values in the block you pass to sortedArrayUsingComparator:. Depending on which values the block gets called with, first can be nil, second can be nil, or both can be nil.
Any message sent to nil returns the equivalent 0 value (e.g. a method returning a float, when sent to nil returns 0.0f, a method returning int when sent to nil returns 0, and a method returning an object sent to nil returns nil). This means that you have the following cases:
[<non-nil> compare:<non-nil>] (returns a valid value)
[<non-nil> compare:nil] (undefined behavior, as per https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/#//apple_ref/occ/instm/NSDate/compare:)
[nil compare:<non-nil>] (returns 0; called on nil)
[nil compare:nil] (returns 0, called on nil)
This means that as the call is being made across the values in the array, some values are being returned that are non-sensical (e.g. [nil compare:[NSDate date]] returns 0, equivalent to NSOrderedSame, which is clearly not true), not to mention the results returned by undefined calls.
In effect, these invalid values are being sorted into strange places in your array. If you had some defined behavior for what should happen if either value is nil, you'd get consistent behavior.
The following code makes the sorting behavior consistent (and should give you similar behavior to the sort descriptors method above):
NSArray* sortedArray = [fetchedReminders sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate* first = [(EKReminder*)a creationDate];
NSDate* second = [(EKReminder*)b creationDate];
if (!first && !second) {
// nils have the same relative ordering
return NSOrderedSame;
} else if (!first) {
// second is not nil; send first toward the end of the array
return NSOrderedDescending;
} else if (!second) {
// first is not nil; send second toward the end of the array
return NSOrderedAscending;
} else {
// Neither is nil; this is valid
return [second compare:first];
}
}];

Core Data Fetch Results Reduced Set of Related Items

I have a NSFetchResult that returns managed objects that contain MANY related objects ( Aobj ->> Bobj). The "Bobj" managed object contains a BOOL attribute "isSet" (stored as NSNumber). The NSFetchResult returns all Aobj objects.
I would like a suggestion for an NSPredicate that would return an Aobj with only those Bojs where isSet is TRUE (#1).
Currently, I enumerate over my NSArray of Aobjs returned by my fetch result so that I can get my filtered NSArray of Aobjs this way:
- (NSArray *)filteredObject:(Aobj *)aObj
{
NSMutableArray* bObjs = [aObj.bObjs mutableCopy];
[bObjs enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Bobj* bObj, NSUInteger idx, BOOL *stop)
{
if (bObj.isSet == [NSNumber numberWithBool:NO])
{
[bObjs removeObject:story];
}
}];
return bObjs;
}
Asked another way: how would I define an NSPredicate for my NSFetchResult that would get all my Aobjs but limit the related Bobjs to those matching Bobj.isSet == YES?
Thanks in advance!
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:#"SELF.bObjs.isSet == YES"];
[myFetchRequest setPredicate:myPredicate];
NSArray *array = [moc executeFetchRequest:myFetchRequest error:&error];
Use a subquery. Subqueries follow this general format:
SUBQUERY(relationship, related_thing, predicate)
relationship is the relationship on the object being evaluated.
related_thing is an individual object in the relationship. It's prefixed by a $ and is then used in the predicate (not shown above, for clarity).
predicate is the predicate to apply to related_thing.
With your example, it would look like (assuming your relationship is called 'bobjs'):
SUBQUERY(bobjs, $obj, $obj.isSet == YES)
Subqueries can be quite powerful. For example, you can also apply collection operators to the subquery:
SUBQUERY(bobjs, $obj, $obj.isSet == YES).#count > 1 would give you each AObj that has at least one object in the 'bobjs' relationship with isSet equal to YES. Obviously, you can use other collections operators or layer logical operations or additional expressions on top of this.

How to get data from unrelated entities using Core Data?

I have these three entities which are not related. How can i get the salary of an employee. I want something like this :
Select C.salary FROM Employee A, Department B, Salaries C Where A.id=B.empid AND B.id=C.deptid AND A.id=12
i need to do the same above operation in core data.
As Martin suggested, the easy way is to set up the needed relationships and traverse them.
But if you don't have the permission to alter the model, you need to work and filter managed in memory object you own once retrieved. In other words, you need to set up NSFetchRequests with the correct NSPredicates.
For example, to retrieve the department for a given employee.
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:#"Department"];
request.predicate = [NSPredicate predicateWithFormat:#"empid", #(12)];
NSError *error = nil;
NSArray *departments = [moc executeFetchRequest:request error:&error];
if(departments) {
// do a NSLog for departments here to see what you have
// here you can access deptid for each department you retrieve
// and with that value run another request against Salaries
// e.g. NSManagedObject* department = [departments lastObject];
// NSNumber* deptid = [department valueForKey:#"deptid"]
} else {
// handle error here
}
Other part is left as excersise ;)

Resources