Core Data NSPredicate casting key value - core-data

I have a data model which has values of type id that I was planning on casting appropriately when needed.
Is it possible for me to cast these as strings and compare them to strings from a UISearchBar using NSPredicate or do I have to use another method?
Maybe something like this:
NSPredicate * predicate;
predicate = [NSPredicate predicateWithFormat:#"CAST(%K) contains[cd] %#", employeeID , theSearchBar.text];

No. The CAST() function doesn't work that way. I think you just have to assume that the id returned from -employeeID is comparable to a string.

Related

Need to write a predicate to search for a date in a core data object's array property (in my case array of dates)

I need to fetch an object using Core Data. The object has a property datesArray(Array of NSDate objects stored as NSData) which I use to store array of dates. I need to check if the array contains todays date and then use the object.
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:#"MyEntity"];
NSError * error;
NSArray * fetchedArray = [context executeFetchRequest:request error:&error];
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"entity.datesArray CONTAINS %#",[NSDate date]];
for (MyEntity * entity in fetchedArray) {
NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:entity.datesArray];
[array filterUsingPredicate:predicate];
if (array.count >0) {
[_myMutableArray addObject:entity];
}
}
You really should not be storing dates like this. You are losing the value of using Core Data. If you have an array of something then that should be on the other side of a relationship which you can then retrieve efficiently from the underlying persistent store.
I suspect that your predicate lacks precision as a date object is down to the nanosecond. If you are looking to match something from "today" then you need to work on something with less precision. Perhaps a string in a specific format or store it as a number and then search within a range (less than X and greater than Y type of search).
Again, storing the actual dates in managed objects makes this question much easier but you are still going to be dealing with a precision problem.

How do I filter CoreData results based on a relationship

I have a list of users, each with
Users.accounts--->Accounts.measurements--->measurement.account
I want to pull all measurements from the measurements "table" where measurement.account=a specific account, and where measurement.type (a property) is "wind speed" as an example.
So I:
Create a fetch request on measurements
I want to create a predicate that says type="wind speed" and account={NSAccount object}
How do I do this?
Measurement type is easy:
*predicate = [NSPredicate predicateWithFormat:#"measuretype = 'air speed'];
Specifying the relationship, I don't know:
myAccountObject *myAccount=[accountFromId:#"6785"];
*accountpredicate = [NSPredicate predicateWithFormat:#"account = ???",myAccount];
In a predicate, %# is a var arg substitution for an object value, so
[NSPredicate predicateWithFormat:#"account = %#",myAccount]
is probably what you are looking for. Even for a constant string this is preferable, because it avoids problems with embedded quotation marks or other special characters, which would
have to be quoted otherwise. So your combined predicate would be:
[NSPredicate predicateWithFormat:#"measuretype = %# AND account = %#",
#"air speed", myAccount]
For more information, see "Predicate Format String Syntax" in the
"Predicate Programming Guide".

Evaluate CoreData entity type in predicate

I have a block predicate that I carefully crafted only to discover you can't use them in Core Data.
NSPredicate *rootContactPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
BOOL isPersonAndRoot = ([[[evaluatedObject entity] name] isEqualToString:#"Person"] && [[(Person*)evaluatedObject accounts] count] == 0);
BOOL isAccountAndRoot = ([[[evaluatedObject entity] name] isEqualToString:#"Account"] && [(Account*)evaluatedObject root] == nil);
return isPersonAndRoot || isAccountAndRoot;
}];
So I need to convert this into a standard String format predicate, but I am unclear on how to check the entity type for the evaluated object. The Person and Account entities are subclasses of a Contact entity which is the type being evaluated in the fetch request. I'm hoping it will see the sub-types.
Check the entity like this:
[NSPredicate predicateWithFormat:#"self.entity = %#", Person.entity];
Swift 4.0 way of checking for entity type using the entity property of the NSManagedObject as per malhal's suggestion.
let entityDescription = NSEntityDescription.entity(forEntityName: "Account", in: managedObjectContext)!
return NSPredicate(format: "entity = %#", entityDescription)
It seems that now you can now simply compare the entity in a predicate, supplying the managed objects entity as the value:
"entity = %#"
Previously:
You can't. The reason is that the predicate will need to be converted so that it can be run on the underlying data store (presumably SQLite). The SQLite database doesn't have any data on the type of the element, it only knows about the keys and values of the objects.
Depending on what you're trying to do, you'll either need to run a single fetch request against the keys known in the super entity. Or you'd need to have 2 fetch requests, separately executed and then combine the 2 result sets.

Creating Core Data predicate to get data within one-to-many relationship

I have a Loans entity with a returnedDate attribute that can contain a date or be NIL. There is a to-many relationship with another entity, Items such that items can be related to many Loans. I would like to create a predicate where I can find all items that do not currently have a loans.returnedDate==NIL.
Assume I currently have the following:
Loan1-item1,returnedDate=NIL
Loan2-item1,returnedDate=5/4/2012
Loan3-item2,returnedDate=NIL.
I would like a predicate that returns no items.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"!(ANY loaned.returnDate==nil)"];
Returns item1.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(NONE loaned.returnDate==nil)"];
Returns item1.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(ANY loaned.returnDate!=nil)"];
Returns item1.
Can someone tell me what logic would return the appropriate results?
So I used the following predicate:
(SUBQUERY(loaned, $sub, $sub.returnDate==nil).#count == 0)
and it is returning the desired results. If you can convince me not to use SUBQUERY, please tell me how.

CoreData: Fetch an object that has a given property AND a given relationship?

I have a CoreData model that looks a bit like this:
Object A:
Results -- A one to many relationship to an indeterminate number of Object B's.
Object B:
Object Name -- A string. (potentially not unique)
Parent -- A singular relationship with Object A.
I am struggling with writing a NSPredicate that will return ObjectB if I know a given Object A and the Object Name string I am looking for. I have tried the following, but always get this error:
"'NSInvalidArgumentException', reason: 'Unable to parse the format string ..."
request.predicate = [NSPredicate predicateWithFormat:#"NameString == %#, SELF IN %#", NameString, ObjectA.results];
request.predicate = [NSPredicate predicateWithFormat:#"(NameString == %#) IN %#", NameString, ObjectA.results];
And so on...
This seems like this should be a simple and obvious thing to do, but I am new at Core Data and am having trouble finding an example that shows this.
Thanks!
You need to use %K.
You may need something like this in your predicate
NSString enitity=#"ObjectA";
NSString attribute=#"results";
request.predicate = [NSPredicate predicateWithFormat:#"NameString == %#, SELF IN %K.%K", NameString, enitity,attributes];
Look here.

Resources