Reputation:
Im trying to sort through my Firebase Data by putting the User with the highest combat power at the top and the lowest at the bottom. However, I've never used NSSortDescriptor
before and it's not working. This crashes and says:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM sortedArrayUsingDescriptors:]: unrecognized selector sent to instance 0x174056e60'
-(void) getObjectCount
{
self.ref = [[FIRDatabase database] reference];
posts = [ref child:@"posts"];
[posts observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
{
myCount = snapshot.childrenCount;
for (snapshot in snapshot.children)
{
self.userPosts = snapshot.value;
NSLog(@"BEFORE Sorting *** : %@",userPosts.description);
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Combat Power" ascending:NO];
NSArray *sorter = @[ sort ];
NSArray *sortedArray = [userPosts sortedArrayUsingDescriptors:sorter];
NSLog(@"After Sorting *** : %@",sortedArray.description);
}
[self.tableView reloadData];
}];
}
Upvotes: 2
Views: 411
Reputation:
The way I got this to work was to use "queryOrderedByChild" in the get method, and then yourNewArray = [yourArray reverseObjectEnumerator].allObjects of the Array.
Easiest way to do it.
Upvotes: 0
Reputation: 4825
By looking in to logs printed before crash snapshot.value is clearly NSDictionary object. Please modify your code as below and it should work.
-(void) getObjectCount
{
self.ref = [[FIRDatabase database] reference];
posts = [ref child:@"posts"];
[posts observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
{
UInt32 myCount = snapshot.childrenCount;
for (snapshot in snapshot.children)
{
id value = snapshot.value;
if ([value isKindOfClass:[NSDictionary class]] {
value = @[value]
}
self.userPosts = value;
NSLog(@"BEFORE Sorting *** : %@",userPosts.description);
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Combat Power" ascending:NO];
NSArray *sorter = @[ sort ];
NSArray *sortedArray = [userPosts sortedArrayUsingDescriptors:sorter];
NSLog(@"After Sorting *** : %@",sortedArray.description);
}
[self.tableView reloadData];
}];
}
Upvotes: 0
Reputation: 1531
I think's it's helpful for you below the code work for me.
//assume userPosts is initialized as an empty mutable array
-(void) getObjectCount
{
[[_ref child:@"posts"] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
{
myCount = snapshot.childrenCount;
for (snapshot in snapshot.children)
{
self.userPosts = snapshot.value;
NSLog(@"BEFORE Sorting *** : %@",userPosts.description);
NSSortDescriptor *sortDescript = [NSSortDescriptor sortDescriptorWithKey:@"Combat Power" ascending:YES];
[userPosts sortUsingDescriptors:[NSArray arrayWithObject:sortDescript]];
NSLog(@"After Sorting *** : %@",userPosts.description);
}
[self.tableView reloadData];
}];
}
and you insert the key for "Combat Power" so you can add the value for string format. for example firebase database show below this format.
{
Combat Power : "1854"
}
Upvotes: 1
Reputation: 35667
Here's an example of reading in a users node and iterating over each user and adding it to an array. Then sorting the array by name
users
-uid_0
name: "User 0"
-uid_1
name: "User 1"
-uid_2
name: "User 2"
//assume self.userArray is initialized as an empty array
// and myRef is the users node shown above
[myRef observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
for ( FDataSnapshot *child in snapshot.children) {
NSDictionary *dict = child.value; //move each child into a dictionary
[self.userArray addObject:dict] //add each dict to the array
}
//sort the array by name
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name"
ascending:YES]; //sorting by 'name' ascending
//now build the sortDescriptor array which is required to perform the sort
NSArray *arrayOfDescriptors = [NSArray arrayWithObject:sortDescriptor];
//now sort the array in place
[self.userArray sortUsingDescriptors: arrayOfDescriptors];
}
The other option is to let Firebase return the data ordered by combat power using orderedBy.
Then insert each child into index 0 of the array when the snapshot is iterated over. The will result in the last object being read in (the highest combat power) being in position 0 in the array.
for ( FDataSnapshot *child in snapshot.children) {
NSDictionary *dict = child.value;
[self.userArray insertObject:dict atIndex:0]
}
Upvotes: 0
Reputation: 3287
userPosts is an NSDictionary type object. You can't sort the items in a dictionary, that doesn't make a whole lot of sense. Put your items in an array first.
Upvotes: 0