Core Data: sorting before saving - iphone

I am adding to a simple entity, a list of names (from an array).
But before saving the entity, I would like them to be sorted. Please could someone be so kind as to tell me how to do this?
I've seen how to sort some fetched data, but I do not know how to do this. A written example would be greatly appreciated.
Many thanks.
NSManagedObjectContext *context = [self managedObjectContext];
NSString *myTempString;
for (databaseMakerVC *aName in peoplesNames.theArray) {
myTempString = [[NSString alloc] initWithFormat:#"%#", aName];
peoplesNamesObject *newObject = [NSEntityDescription
insertNewObjectForEntityForName:#"peoplesNamesObject"
inManagedObjectContext:context];
newObject.aName = myTempString;
}
// *** Do the sorting here!? ***
// Save the context
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"peoplesNamesObject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"aName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error;
NSArray *array=[context executeFetchRequest:fetchRequest error:&error];
This will work

EDIT
Just add a sort descriptor after you insert the object
The sortDescriptorWithKey looks for a key in the array. In a array I created I assigned a key to "createdDate" and sorted it by that. So you would assign a key of "name" and use the code below
NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:NO];
[peoplesNames.theArray sortUsingDescriptors:[NSArray arrayWithObject:sort]];

Related

Core Data - Sorting records that are fetched as part of relationship

I have the following entities....
Person
|
--- Review
I retrieve a list of Person records .... and then I am directly able to reference the review records via Person.Reviews (which is nice and easy without having to write any NSFetch statements.)
My question is how do I sort the Reviews by date (there is a date attribute within the review entity) ? So that when I reference Person.Reviews they are in date order ?
My temp fix is to sort the array outside of the fetch
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"startDate" ascending:YES]];
NSArray *reviewList;
reviewList = [[[NSArray alloc] initWithArray:[person.reviews allObjects]] sortedArrayUsingDescriptors:sortDescriptors];
Many Thanks
Assuming you mean that you want to fetch the list of Review entities for a given person, sorted by date:
You can use NSFetchRequest, NSPredicate and NSSortDescriptor to do a filtered Core Data fetch with sorting of results.
Example:
NSManagedObjectContext *context = <#Get the context#>;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Review"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"person == %#", thePerson];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"startDate"
ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
}
The above code assumes your Review entity has a date field called startDate and a field called person which is a link back to the person.
After this code has run, fetchedObjects contains Review objects sorted into the review date order (and only reviews objects for the person of interest).
For more info, please read https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/fetching.html
Use a NSFetchRequest and NSSortDescriptor to sort your entity by date (ascending or not) :
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"YourEntityName" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entityDesc];
// Sort By date
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

iPhone:similar to "where" type clause in core data

I am using core data first time in my application for my problem I have done google a lot but I didn't find specific solution.
I have Entity:SubCategory
Attributes:mainCategoryId,subCategoryName.
Now I want to fetch the data like
Select subCategoryName from SubCategory where mainCategoryId=1;
The code which I have implemented is as follows:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SubCategory" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SubCategoryName == %#",#"Triangular1"];
[request setPredicate:predicate];
NSError *error;
arrSubCategory = [managedObjectContext executeFetchRequest:request error:&error];
How can I fetch similar kind of data in coredata
share your ideas
thanx in advance.
From your question what you need is,
[NSPredicate predicateWithFormat:#"mainCategoryId = %#",#"1"];
So your code will look like,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"SubCategory" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"mainCategoryId = %#",#"1"];
[request setPredicate:predicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"subCategoryName: %#", [info valueForKey:#"subCategoryName"]);
}
The above is just a sample code. Actual implementation could be different based on your requirement.
A tutorial on coredata is here. Check that out as well.
You can do it like this
NSString *maincategoryId = #"1";
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"SubCategory"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"rubriqueid == %#", maincategoryId]];
and after you call your NSMutableArray to put your result:
NSMutableArray *answensmuarray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

How to sort a fetch in Core Data

I'm doing a fetch of data to show it in a UITableView, I do the fetch but I want to sort them by date of creation or by any sort method.
Here is the method:
-(NSArray *) lesStations {
NSManagedObjectContext *moc = [[AppDelegate sharedAppDelegate]managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:moc];
[fetch setEntity:entity];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];
if (!result) {
return nil;
}
return result;
}
This should work
-(NSArray *) lesStations {
NSManagedObjectContext *moc = [[AppDelegate sharedAppDelegate]managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:moc];
[fetch setEntity:entity];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];
if (!result) {
return nil;
}
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:"creationDate" ascending:YES];
NSArray *sortedResults = [result sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
return sortedResults;
}
You have 2 options: get the results sorted or sort the NSArray with the results:
NSFetchRequest could be set a NSArray of NSSortDescriptor
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"place" ascending:NO]; //the key is the attribute you want to sort by
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
You can also sort the returned NSArray (see all instance methods of NSArray starting with sortedArray...)
I suggest using the first approach when working with CoreData. The second one is just informative when working with arrays...
You can sort fetch results by setting sortDescriptors for fetch, e.g.
fetch.sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey: ascending: selector:], nil];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];

iphone core data save not working

Im trying to save a list of Device classes (a custom class) using Core Data and retrieve it. But After I save it, my query, which is VERY simple, doesnt return any records.
My call to save the records always returns YES and no errors:
BOOL resultOfSave = [managedObjectContext save:&err];
My predicate for searching by the property userLogin is like so:
- (NSArray *) devicesForUser:(NSString *)username
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Device" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userLogin = %#", username];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"macAddress" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error = nil;
NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error];
if (fetchResults == nil) {
// Handle the error.
NSLog(#"ERROR: nil fetch result array");
}
[request release];
NSLog(#"devicesForUser [%#] count %d", username, [fetchResults count]);
return fetchResults;
}
but I always get zero results, if I get rid of the predecate, I get all the objects, and if I loop through them I can see that the userLogin property for at least one of the object IS set to the username that I pass in...
Has anyone ever had an issue like this???
Thanks for any help you can give
Mark
In your predicate, change:
#"userLogin = %#"
...to:
#"userLogin == %#"

Fetch object by property in Core Data

In my iPhone project, I want to write a function that checks wether there's an object in my Core Data ManagedObjectContext with a given value for a certain property, say some_property.
If there's already an object with some_property == 12, I want the function to return the object, otherwise, I want to create the object, or at least return nil.
How would I do that?
The following snippet shows how to retrieve the objects matching a specific predicate. If there are no such objects, the snippet shows how to create a new object, save it and return it.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"YourEntityName" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"property == %#", value];
[request setPredicate:predicate];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"yourSortKey" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
NSError *error = nil;
NSArray *result = [managedObjectContext executeFetchRequest:request error:&error];
[request release];
[sortDescriptor release];
[sortDescriptors release];
if ((result != nil) && ([result count]) && (error == nil)){
return [NSMutableArray arrayWithArray:result];
}
else{
YourEntityName *object = (YourEntityName *) [NSEntityDescription insertNewObjectForEntityForName:#"YourEntityName" inManagedObjectContext:self.managedObjectContext];
// setup your object attributes, for instance set its name
object.name = #"name"
// save object
NSError *error;
if (![[self managedObjectContext] save:&error]) {
// Handle error
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
return object;
}
It's better if you don't do multiple fetching if you want to check for certain properties on the local data. Just do one fetch request using a pre-populated array and then iterate or filter the results.
This is a code snippet from Core Data Programming Guide "Implementing Find-or-Create Efficiently":
// get the names to parse in sorted order
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:#"\n"]
sortedArrayUsingSelector: #selector(compare:)];
// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:
[NSEntityDescription entityForName:#"Employee" inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: #"(employeeID IN %#)", employeeIDs]];
// make sure the results are sorted as well
[fetchRequest setSortDescriptors: [NSArray arrayWithObject:
[[[NSSortDescriptor alloc] initWithKey: #"employeeID"
ascending:YES] autorelease]]];
// Execute the fetch
NSError *error;
NSArray *employeesMatchingNames = [aMOC
executeFetchRequest:fetchRequest error:&error];