Exactly Matched NSString in Core Data iOS - 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];

Related

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);
}
}

XMPP, CoreData - how to load only self and destination user messages?

I save to core data and load all messages with code below, but how can I load only messages for 2 users, for self user and for destination user, I want base it on user JID.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [[self appDelegate].xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
fetchRequest.entity = messageEntity;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:YES];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
//Now you get the NSArray with element type of "XMPPMessageArchiving_Message_CoreDataObject"
assuming your message objects have a from relationshit to a User entity.
As simple as adding (before executing the request):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"from = %# OR from = %#",selfUser,otherUser];
Where selfUser and otherUser are User core data managed objects or managed object IDs of users.
if you use a field identifier (highly not recomended):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJID.bare = %# OR bareJID.bare = %#",selfUser.jid,otherUser.jid];
You might want to read THIS
I have used following method and it worked correctly :)
-(void)checkForPastMessageAndDisplayIt
{
NSString *strmyid = #"user1#domain";
NSString *strBuddy = #"user2#domain";
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_message_achiving];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *messagesArray = [moc executeFetchRequest:fetchRequest error:&error];
[messagesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id messageObject = [messagesArray objectAtIndex:idx];
if ([messageObject isKindOfClass:[XMPPMessageArchiving_Message_CoreDataObject class]]) {
XMPPMessageArchiving_Message_CoreDataObject *currentMessageCoreDataObject = (XMPPMessageArchiving_Message_CoreDataObject*)messageObject;
XMPPMessage *message = currentMessageCoreDataObject.message;
if (message!=nil) {
[messages addObject:message];
}
}
}];
}
You can use like that
-(void)testMessageArchiving {
NSString *strmyid = #"myid";
NSString *strBuddy ="toid";
NSLog(#"my id and buddy is is %# and %#",strmyid,strBuddy);
XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
NSError *error;
NSArray *messages = [moc executeFetchRequest:request error:&error];
// NSLog(#"the history of messages is %#",messages);
[self print:[[NSMutableArray alloc]initWithArray:messages]];

How to fetch a single object from Coredata using a predicate

I am trying to fetch a single object from my coredatabase, however it keeps returning null. My method is based off another method which returns every value from the coredata object that I am accessing..
I have never tried this before and have tried reading apples documents but its just not making sense.. this is what my method looks like
- (NSMutableArray *)readSelectedInstall:(NSString *)projIDString {
NSManagedObjectContext *context = [self managedObjectContext];
if (context == nil) {
NSLog(#"Nil");
}
else {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"InstallProject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ProjID==%#", projIDString];
[fetchRequest setPredicate:predicate];
NSError *error;
NSMutableArray *installProjectDictionaryArray = [[NSMutableArray alloc] init];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (InstallProject *installProj in fetchedObjects) {
NSMutableDictionary *tempInstallProjectDictionaryArray = [[ NSMutableDictionary alloc] init];
[tempInstallProjectDictionaryArray setObject:installProj.companyName forKey:#"CompanyName"];
[tempInstallProjectDictionaryArray setObject:installProj.projNo forKey:#"ProjNo"];
[tempInstallProjectDictionaryArray setObject:installProj.projID forKey:#"ProjID"];
[installProjectDictionaryArray addObject:tempInstallProjectDictionaryArray];
}
return installProjectDictionaryArray;
}
return nil;
}
any help getting me to return a single item thats projID matches the projIDString would be greatly appreciated.
Import NSManagedObject(InstallProject) and fetch one object like this,
-(InstallProject *)readSelectedInstall:(NSString *)projIDString
{
NSArray *fetchedObjects;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"InstallProject" inManagedObjectContext: context];
[fetch setEntity:entityDescription];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"(ANY ProjID contains[cd] %#)",projIDString]];
NSError * error = nil;
fetchedObjects = [context executeFetchRequest:fetch error:&error];
if([fetchedObjects count] == 1)
return [fetchedObjects objectAtIndex:0];
else
return nil;
}
What about the fetchLimit on the fetchRequest You can set that to 1
The fetch limit specifies the maximum number of objects that a request should return when executed.
E.g. in Swift:
let fetchRequest = NSFetchRequest(entityName: "Cart")
fetchRequest.fetchLimit = 1
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(Cart.creationDate), ascending: true)]
Edit: The sortDescriptors are set only because I was using this fetchRequest with an NFRC, you can just execute the fetchRequest too:
do {
let fetchRequest = NSFetchRequest(entityName: "Cart")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "name == %#", mainCart)
var objects: [Cart]
try objects = mainMoc.execute(fetchRequest) as! [Cart]
} catch {
}

Core Data Predicate To Many

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

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