Core Data Predicate To Many - ios

I have a core data model that has a one to many relationship, there is a category, and it can contain many subcategories.
Category <---->> Subcategory
I am trying to perform a fetch that checks if a particular Category contains a Subcategory with a particular name. Let's say I have two categories below, I want to fetch to see if there are any subcategories name "Apple" in the Category named "Fruits".
Vetegables
- Carrot
- Lettuce
Fruits
- Apple
- Orange
- Pear
Code:
- (SubCategory *)searchForSubCategoryWithName:(NSString *)subCategory
inCategory:(Category *)category
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SubCategory" inManagedObjectContext:self.beer.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == [c] %#", subCategory];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *fetchedObjects = [self.beer.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects != nil && fetchedObjects.count > 0) {
return [fetchedObjects objectAtIndex:0];
}
else {
return nil;
}
}

Try looking for category entity which has subcategory you like not the other way around, then return category.subcategory from results. I am not sure how your NSManagedObjects look like but try this:
- (SubCategory *)searchForSubCategoryWithName:(NSString *)subCategory
inCategory:(Category *)category
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Category" inManagedObjectContext:self.beer.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subcategory.name == [c] %# AND name == %#", subCategory, category.name];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *fetchedObjects = [self.beer.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects != nil && fetchedObjects.count > 0) {
Category *categoryManagedObject = [fetchedObjects objectAtIndex:0];
return categoryManagedObject.subcategory;
}
else {
return nil;
}
}
...or just add category to your predicate, you should have it in your subcategory managed object definition:
- (SubCategory *)searchForSubCategoryWithName:(NSString *)subCategory
inCategory:(Category *)category
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Category" inManagedObjectContext:self.beer.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == [c] %# AND category == %#", subCategory, category];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *fetchedObjects = [self.beer.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects != nil && fetchedObjects.count > 0) {
return [fetchedObjects objectAtIndex:0];
}
else {
return nil;
}
}

Related

Save the result of setPredicate to NSString

I have created NSPredicate to search the string in my coredata.
so in this case does anyone know how to save the result [fetchRequest setPredicate:predicate]; in NSString.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",
mytext];
[fetchRequest setPredicate:predicate];
Write Your Table Name in #"YOUR_ENTITY_NAME"
Make sure that your table contains name column
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"YOUR_ENTITY_NAME"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", mytext]];
NSMutableArray *arrResult = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"%#", arrResult); //output
I think this will help you
NSArray *fetchedObjects;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"your entity" inManagedObjectContext: context];
[fetch setEntity:entityDescription];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", mytext]];
NSError * error = nil;
fetchedObjects = [context executeFetchRequest:fetch error:&error];
if([fetchedObjects count] == 1)
NSLog(#"%#",[fetchedObjects objectAtIndex:0]);

Unable to fetch specific column that from core data

I have created a an entity called Statutory with four columns namely name,complianceName,statMappingName,country
i want a get all complianceName names that matches a specific statMappingName. Following is my code
NSString *nameToGet = self.statNameArray[indexPath.row] ;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"complianceName = %#", nameToGet];
[fetch setPredicate:predicate];
NSLog(#"n %#",predicate);
NSError *error = nil;
NSArray *results = [[self managedObjectContext] executeFetchRequest:fetch error:&error];
if(results) {
NSLog(#"Entities with that name: %#", results);
} else {
NSLog(#"Error: %#", error);
}
But it is not providing the compliance name specific to that statMappingName. How can I be able to get all complianceName that has a specific statMappingName?
Try this:-
NSString *firstName = statMappingName;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"firstName == %#", firstName]];
If you want to fetch specific column from core data
You can use the below method:-
NSEntityDescription *entity = [NSEntityDescription entityForName:entityname inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setReturnsObjectsAsFaults:NO];
[request setEntity:entity];
[request setFetchLimit:1];
[request setPredicate:[NSPredicate predicateWithFormat:#"(complianceName LIKE %#)",nametoGet]];
NSError *error = nil;
NSMutableArray *tempDataArr = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
Note:-
*entityname: Your entity name
*self.managedObjectContext : Your managedobjectcontext
To Get All compliance Name use the below method
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSMutableArray *tempDataArr =[NSMutableArray new];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"(ANY complianceName LIKE %#)",nametoGet]];
tempDataArr = [[self.managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
try these code for contains statMappingName
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"complianceName contains[c] %#", statMappingName];

Exactly Matched NSString in Core Data iOS

I've my entity in CoreData named as myentity and an attribute named as myuniqueid and I want to run an SQL query as follows:
Select * from myentity where myuniqueid == 1000
How can I get my specified rows where it matches as in SQL query? such that I want to filter all rows where myuniqueid is 1000.
My Code:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [self managedObjectContext];
if (context == nil) {}
else {
NSEntityDescription *entity = [NSEntityDescription entityForName:#"myentity" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"myuniqueid == 1000"];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];
NSArray *items = [context executeFetchRequest:fetchRequest error:nil];
for (int i=0; i<4; i++) {
NSManagedObject *mo = [items objectAtIndex:i]; // assuming that array is not empty
id value = [mo valueForKey:#"myuniqueid"];
NSLog(#"SENDER: %#",value);
}
}
Im getting error: 'Unable to generate SQL for predicate (myuniqueid == 1000) (problem on RHS)'
Try this predicate :
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"myentity"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"myuniqueid == %#", #(1000)];
NSArray *items = [[self managedObjectContext] executeFetchRequest:request error:nil];

How to Fetch Data From Core Data Based On Two way RelationShip?

In my sample App i have two Entity Called Accounts and Customer
and for that Entities i have created two NSManagedObject subClasses
core data entities http://i.stack.
imgur.com/zmt1N.png
now exactly i don't know whether its correct or what, i have to save to these core data entities and retrieve the detail like the "customer who ever having more than three accounts in accounts table"
expecting a little detailed explanation. Thanks in Advance
Use NSPredicate
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/index.html
A trivial example with a "search" for name with case insensitive string:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"customer"];
request.predicate = [NSPredicate predicateWithFormat:#"name LIKE[c] %#", #"Amazon"];
NSArray *matches = [self.managedObjectContext executeFetchRequest:request error:nil];
As per NSPredicate Class Reference linked above:
You can create predicates for relationships, such as:
group.name like "work*"
ALL children.age > 12
ANY children.age > 12
this is what i expected to do. Thanks for the help
-(void)savingDummyDatas
{
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Customer" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
//execution starting time
NSDate *methodStart = [NSDate date];
//
if ([objects count] == 0)
{
#pragma mark - Entity Insertion With Relation
//for (int i=1; i<=100000; i++) {
//1
Customer *custObj1 = [NSEntityDescription insertNewObjectForEntityForName:#"Customer" inManagedObjectContext:context];
custObj1.name = #"Yeswant";
// add accoutns for customer
Accounts *acObj1 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj1.accountNumber = #"001";
[custObj1 addCust_relationObject:acObj1];
Accounts *acObj2 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj2.accountNumber = #"002";
[custObj1 addCust_relationObject:acObj2];
Accounts *acObj3 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj3.accountNumber =#"003";
[custObj1 addCust_relationObject:acObj3];
Accounts *acObj4 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj4.accountNumber =#"004";
[custObj1 addCust_relationObject:acObj4];
//2
Customer *custObj2 = [NSEntityDescription insertNewObjectForEntityForName:#"Customer" inManagedObjectContext:context];
custObj2.name= #"Bharath";
// add accoutns for customer
Accounts *acObj01 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj01.accountNumber = #"010";
[custObj2 addCust_relationObject:acObj01];
Accounts *acObj02 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj02.accountNumber = #"011";
[custObj2 addCust_relationObject:acObj02];
Accounts *acObj03 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj03.accountNumber =#"101";
[custObj2 addCust_relationObject:acObj03];
//3
Customer *custObj3 = [NSEntityDescription insertNewObjectForEntityForName:#"Customer" inManagedObjectContext:context];
custObj3.name = #"Ansal";
// add accoutns for customer
Accounts *acObj001 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj001.accountNumber = #"001";
[custObj3 addCust_relationObject:acObj001];
Accounts *acObj002 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj002.accountNumber = #"002";
[custObj3 addCust_relationObject:acObj002];
Accounts *acObj003 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj003.accountNumber =#"003";
[custObj3 addCust_relationObject:acObj003];
Accounts *acObj004 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj004.accountNumber =#"004";
[custObj3 addCust_relationObject:acObj004];
//4
Customer *custObj4 = [NSEntityDescription insertNewObjectForEntityForName:#"Customer" inManagedObjectContext:context];
custObj4.name = #"Vijeesh";
// add accoutrns for customer
Accounts *acObj0001 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj0001.accountNumber = #"010";
[custObj4 addCust_relationObject:acObj0001];
Accounts *acObj0002 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj0002.accountNumber = #"011";
[custObj4 addCust_relationObject:acObj0002];
Accounts *acObj0003 = [NSEntityDescription insertNewObjectForEntityForName:#"Accounts" inManagedObjectContext:context];
acObj0003.accountNumber =#"101";
[custObj4 addCust_relationObject:acObj0003];
[context save:nil];
}
to Retrive these saved Data and filter or Fetch Using Predicate
-(void)fetchCoreDAta
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSFetchRequest *fetchRequest1 = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Customer" inManagedObjectContext:self.managedObjectContext];
NSEntityDescription *entityAccounts = [NSEntityDescription entityForName:#"Accounts" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest1 setEntity:entityAccounts];
// [fetchRequest1 setEntity:entity];
#pragma mark - using predicates for fetching customer name who having three accounts
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"cust_relation.#count == 4"];
// NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"ANY account_relation.name LIKE[c] 'Vijeesh'"];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"ANY account_relation.name like 'Vijeesh'"];
NSString *value1 =#"Ansal";
NSString *value2 =#"Vijeesh";
// NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"(name == %#) AND (SUBQUERY(subs, $x, $x.numbervalue == %# or $x.numbervalue == %#).#count > 0)", #"Yeswant", value1, value2] ;
[fetchRequest setPredicate:predicate];
[fetchRequest1 setPredicate:predicate1];
NSError *error = nil;
NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSArray *resultAccounts = [self.managedObjectContext executeFetchRequest:fetchRequest1 error:&error];
if (error)
{
NSLog(#"Unable to execute fetch request.");
NSLog(#"%#, %#", error, error.localizedDescription);
}
else
{
NSLog(#"%#", result);
NSLog(#"accounts:%#",resultAccounts);
NSMutableArray * userNAmeArray = [result valueForKey:#"name"];
NSMutableArray * accountsnumberArray = [resultAccounts valueForKey:#"accountNumber"];
NSLog(#"names:%#",userNAmeArray);
NSLog(#"acnums:%#",accountsnumberArray);
}
}

Unique NSManagedObject Attribute

What's the best way to make an NSManagedObject attribute Unique?
For example, should willSave or validateForInsert: or validateForUpdate: managed object methods be used to check if the value entered in attributeUnique is Unique? And, how exactly?
I ended up writing an NSManagedObject category method, and using the NSManagedObject's validation method:
- (BOOL)isValueUniqueForKey:(NSString *)key {
NSEntityDescription *entity = [NSEntityDescription entityForName:[self.entity name]
inManagedObjectContext:self.managedObjectContext];
id value = [self valueForKey:key];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%# = %#", key, value];
fetchRequest.predicate = predicate;
NSError *error = nil;
NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest
error:&error];
if (count > 1) {
return NO;
}
return YES;
}

Resources