NSSortDescriptor with two equally important keys - ios

I am constructing a NSFetchedResultsController for my entity, which has two attributes, let's say a shortName and a longName. All of the managed objects only have either the shortName or the longName.
How can I sort the objects based on both attributes (or rather the one which is not null) at the same time?
Clearly the following will not work in my case:
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:#"shortName" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:#"longName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];

It's quite interesting, but Im almost sure it is not possible to do. Just assigning shortName to the longName attribute, if there is no longName, while inserting to your db would be the best solution for me and simply sorting on longName.

Related

Need assistance regarding sorting NSMutableArray

I have an NSMutableArray and on every index I have another NSMutableArray but of different length like 2, 3, 4. I want to sort main array that the inside array who have bigger length come on top.
You can sort them using a descriptor:
NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
[myArray sortUsingDescriptors:#[sd]];
The above code creates one sort descriptor on the property called "count" in descending order.
//Create a sort descriptor based on count using NSSortDescriptor class as-
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
//& sort your main array using sort descriptor
[mainArray sortUsingDescriptors:#[sortDescriptor]];

Sorting NSMutableArray with custom class by date

I have NSMutableArray named "allConversations" that contains a custom class "Users".
every user have property "lastMessageDate".
e.x : user.lastMessageDate;
what is the best way to sort the array by date?
I have this code :
NSMutableArray *arrCopy = [[NSMutableArray alloc]initWithArray:unSortedArr];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"lastMessageDate" ascending:TRUE];
[arrCopy sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
but I don't know how to implement it in this situation
it seems all you are missing is the assignment. This should work for you.
arrCopy = [arrCopy sortedArrayUsingDescriptors:#[[[NSSortDescriptor alloc] initWithKey:#"createdAt" ascending:YES]]];

Equal Core Data statement to SQLite statement (order by ... desc..)

I'm using a statement in sqlite to select specific object from table:
NSString *statment = [NSString stringWithFormat:#"SELECT * FROM %# ORDER BY %# DESC LIMIT 1", TRAP_TABLE, DISTANCE_TO_CLOSE_POINT];
I want to do the same thing using core data.
How should I mix the NSPredicate & NSSortDescriptor in order to do the same?
EDIT:
This is what I did, didn't tried it yet:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:DISTANCE_TO_CLOSE_POINT ascending:NO selector:#selector(localizedCompare:)];
The NSPredicate is like the where clause of a SQL statement. Your example doesn't have a where clause.
In a NSFetchRequest you can add sort descriptors to handle the 'order by'. Also in the NSFetchRequest you can set a fetch limit.
From there you pass the NSFetchRequest to the NSManagedObjectContext and receive your results.
Update 1
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:DISTANCE_TO_CLOSE_POINT ascending:NO selector:#selector(localizedCompare:)];
That is overkill in this situation. I am guessing the value you are sorting on is a number which means you don't need localizedCompare: since you are not working with strings. So you can simplify it to:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:DISTANCE_TO_CLOSE_POINT ascending:NO];
And if you are in an ARC project, even reduce it down to:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:DISTANCE_TO_CLOSE_POINT ascending:NO];
Which can then be thrown directly into the NSFetchRequest:
[fetchRequest setSortDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:DISTANCE_TO_CLOSE_POINT ascending:NO]]];

NSSortDescriptor using the minimum value of a date in a related object

I have a Core Data entity, MediaAsset. I have another called UploadAttempt which tracks all of the attempts we've made to upload that MediaAsset to our central server. I would like to fetch MediaAssets from the datastore ordered by the first UploadAttempt.
MediaAsset has 3 UploadAttempts, A, B, and C. UploadAttempt has an attemptDate attribute and I would like to find the earliest UploadAttempt for each MediaAsset and use that as the sorting.
I would like to create an NSSortDescriptor something along the lines of:
order by MediaAsset.uploadAttempts.attemptDate where attemptDate is the earliest attemptDate for that particular MediaAsset.
Does that make sense? Any help is appreciated.
(note: assume I cannot add an additional attribute to the MediaAsset. This is already existing data and I can't alter it.)
If I understand your question correctly, the following should work. If not, please ping me again, we will understand and correct it together.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"UploadAttempt"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entityDesc];
NSError *error = nil;
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *dateSortedAttempts = [self.managedObjectContext executeFetchRequest:fetchRequest
error:&error];
NSSet* mediaAssets= [NSSet setWithArray:[items valueForKeyPath:#"#distinctUnionOfObjects.MediaAsset"]];

Need assistance regarding sorting in fetchedResultsController

My table is populating using fetchedResultsController. I want to sort the data but conditionally on two things:
Name of users.
Scores.
a. If there is no score the table must to sorted with users name alphabetically.
b. If any user has score that must go on top.
I tried this
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"userScore" ascending:NO];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, sd2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
It works fine but after app restart table is sorted only by user name.

Resources