Fetching data from entity using nspredicate - ios

I have core data entity called "Songs" which contains details of different songs details. One of the attribute of this entity is "Language". I want to fetch all songs with Language Spanish. But if number of songs with Spanish is zero, then it should fetch all songs with default language, thats english. Is this possible through single NSPredicate if I know default language and needed language.

You can do it this way.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
//here strLanguage is string with the name of selected language
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"Language == %#",strLanguage];
[request setPredicate:predicate];
[request setEntity:entity];
NSMutableArray* mutableFetchCategory = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if ([mutableFetchCategory count] > 0)
{
for (NSManagedObject *info in mutableFetchCategory)
{
NSLog(#"%#",info);
//Extract data from each "info" object and store it in an array and display it in tableview
}
}
else
{
// Repeat the same code [or u can use functions for reusability] with language "English".
}
You can also refer this link

Related

How to fetch specific records in Core data

I am a new bid in iOS development. I am using NSManagedObject of Core Data to perform Insert and Fetch operations. It works perfectly fine. But the problem is, I want to fetch only some selected records (where condition in MySQL) from the table.
For e.g. "select name from users where city='Pune'";
I found NSPredicate to fetch filtered data. But it gives all the data in array and not just the selected one. For e.g. if result for above query is:
Anu
Then the NSPredicate result will give:
fname = Anu
lname = Padhye
city = Pune
id = 3
Is there a way to only fetch selected record/s in iOS Objective-c? Following is the code snippet I am using for NSManagedObject:
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"User"];
valueData = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSEntityDescription *productEntity=[NSEntityDescription entityForName:#"User" inManagedObjectContext:managedObjectContext];
NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
[fetch setEntity:productEntity];
NSPredicate *p=[NSPredicate predicateWithFormat:#"id == %d", 3];
[fetch setPredicate:p];
//... add sorts if you want them
NSError *fetchError;
NSArray *fetchedProducts=[valueData filteredArrayUsingPredicate:p];
Try this:
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"User"];
request.predicate = [NSPredicate predicateWithFormat:#"city == %# && id == %d", #"Pune", 3];
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES]];
NSArray *results = [managedObjectContext executeFetchRequest:request error:nil];
Results array should now contain all records who have Pune as their city with the id of 3.

fetching specific data from core data database and displaying in UITableView

I currently have a table view that displays all the contents of the database Entity: ExData.
ExData has an attribute tag of string type.
What my problem is that i would like to display the contents of the ExData in the table view but only the entries that have a tag set of 2 for example.
The tag is to be sent from the previous view controller but this can be sorted out later as firstly i would just like to hard code only one tag value entries being displayed
ExDatasArray is a mutable Array.
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"ExData"];
self.ExdatasArray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
Above is how the data from ExData is being fetched...
To fetch specific data, you add a predicate to the fetch request:
NSString *theTag = ...
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"tag == %#", theTag];
[fetchRequest setPredicate:predicate];
Remark: If you are displaying the result set in a table view, you might also consider to
use a NSFetchedResultsController.
If I understand your question correctly, you are trying to limit the results of the fetchRequest. Use an NSPredicate to specify the query and if desired an NSSortDescriptor to sort it. Below I assume that your tag attribute is named tag, and that searchTagValue has been set appropriately.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"ExData"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"tag == %#", searchTagValue];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"tag" ascending:YES]];
NSError *error;
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (!result) {
// handle error
}
else {
self.ExdatasArray = [results mutableCopy];
}

Core Data duplicate entries

I'm importing data from an API that's giving me JSON data. Each object that gets added into core data has an attribute named "id". I want to be able to check if the id is already in core data after the initial import. I have written this code out for it so far:
- (void)mergeData: (NSString *)entityDescription {
NSPredicate *pred = [NSPredicate predicateWithFormat:#"id == %#", _bank.id]; // Bank is the entity
// id is the key from the raw JSON
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSError *error = nil;
[fetch setEntity:[NSEntityDescription entityForName:#"Banks" inManagedObjectContext:self.managedObjectContext]];
[fetch setPredicate:pred];
NSArray *items = [self.managedObjectContext executeFetchRequest:fetch error:&error];
for (NSManagedObject *object in items) {
// Loop over all the items and check to see if the ids match with any ids from the feed
// if any of them don't match, add the new ids
if (!match) {
// add new object
// I'm not sure how to implement this part
}
}
But I know it's not complete and I'm not sure how to implement the rest of the code for this part. Any help would be appreciated.

ios NSFetchRequest for two related tables

my program has a sqlite database with two related tables. One called "Rank" and other one called "Requirement"
I want to fetch all rows from the "Requirement" table that has a relationship with the specific row in a "Rank" table. Following is my code, it grabs the whole table, but I get the specified rows only according to the above mentioned rule.
-(NSArray *) getAllRequirementsForTheRank:(Rank *) rank
{
NSError *error;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Requirement" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSPredicate *searchType = [NSPredicate predicateWithFormat:#"Rank = %#", rank];
[fetchRequest setPredicate:searchType];
NSArray *scoutRequirementArray = [self.context executeFetchRequest:fetchRequest error:&error];
for (Requirement *r in scoutRequirementArray)
{
NSLog(#"Requirementttt : %# :", r.requirementName);
}
return scoutRequirementArray;
}
If you have the relationship modelled in core data, just get the linked objects from the relationship property. You don't need another fetch request. rank.requirements will give you an NSSet of everything you need. (I'm assuming names for your object and properties here).

Core Data filter results for a single attribute and set the text of a UILabel

Baiscally I want to update a UILabel with results of a Core Data query. I have a UILabel with the following text "root has X credits". I want to search Core Data for entity "Account" then refine the search to look for just the "root" account, then refine the search for just the attribute "credit" located in the "root" account. Finally I want update the UILabel to read "root has 0 credits" (or however many credits the Core Data query describes.
So far I have the following code,
- (void)rootCreditAmount {
// Core Data - root credit amount
NSFetchRequest *request = [[NSFetchRequest alloc] init];
// define our table / entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
[request setEntity:entity];
// filter results to just root user
NSPredicate *username = [NSPredicate predicateWithFormat:#"root"];
[request setPredicate:username];
// fetch records and handle error
NSError *error;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:& error] mutableCopy];
if (!mutableFetchResults) {
// handle error.
// should advise user to restart
}
NSLog(#"mutablefetchresults = %#",mutableFetchResults);
}
Needless to say this code is causing my app to crash at the moment.
Change your predicate statement to:
[NSPredicate predicateWithFormat:#"username == root"];
Change "username" to whatever your field name is. See here for more info about formatting predicate strings.
Well thanks to the help of #skytz in chat.stackoverflow.com I was able to do what I needed. I ended up not using NSPredicate. The below method ended up solving my problem. But in the spirit of being a nice guy I'll give the credit to #melsam for the punctionality.
- (void)rootCreditAmount {
// Core Data - root credit amount
NSFetchRequest *request = [[NSFetchRequest alloc] init];
// define our table / entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
[request setEntity:entity];
// fetch records and handle error
NSError *error;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults) {
// handle error.
// should advise user to restart
}
// refine to just root account
for (Account *anAccount in mutableFetchResults) {
if ([anAccount.username isEqualToString:#"root"]) {
NSLog(#"root credit = %#",anAccount.credit);
_lblRootCredit.text = [NSString stringWithFormat:#"root has %# credits.",anAccount.credit];
}
}
}

Resources