I have a few objects in a Parse database, a few are as shown below. I would like to sort these objects by highScore, which is stored as a number.
(
"<Score: 0x7fee53740700, objectId: zMjL3eNWpI, localId: (null)> {\n Score = \"High Score: 60\";\n TeamName = \"Team0\";\n highScore = 60;\n}",
"<Score: 0x7fee534b5080, objectId: nysaJjYsth, localId: (null)> {\n Score = \"High Score: 86\";\n TeamName = Team1;\n highScore = 86;\n}",
"<Score: 0x7fee535f6ad0, objectId: 7Hj8RP4wYD, localId: (null)> {\n Score = \"High Score: 23\";\n TeamName = Team2;\n highScore = 23;\n}"
)
I have the following code which I loop over the objects and pull out the Number highScore for each object, but I am not sure how to continue. Is there a way I can return (NSComparisonResult)NSOrderedAscending? If anyone has any advice please let me know. Thanks.
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];//class name is Score
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
for (int i = 0; i<=objects.count; i++){
NSArray *array = [objects objectAtIndex:i];//Selects the first "object" from all the "objects"
NSNumber *test= [objects objectAtIndex:i];
array = [array valueForKey:#"highScore"];
test = [test valueForKey:#"highScore"];
test1 = [test intValue];//test1 is the current database object highScore for the current object
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Parse.com offers a great iOS SDK that already gives you out of the box what you are looking for. When you make a PFQuery, Parse gives you the option to order the results the way you would like. I believe you should try this:
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query orderByAscending:#"highScore"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
for (PFObject *object in objects) {
NSLog(#"High Score is %d", [object["highScore"]intValue]);
}
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Related
I have a PFQuery that gets the current participants of a particular event:
PFQuery *getcurrentparticipants = [PFQuery queryWithClassName:#"Event"];
[getcurrentparticipants selectKeys:#[#"Participants"]];
[getcurrentparticipants whereKey:#"objectId" equalTo:ObjectID];
[getcurrentparticipants findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *newParticipantsArray = [[NSMutableArray alloc]init];
if([objects[0] valueForKey:#"Participants"] == nil){ // If object retrieved in objects is null. If there are 0 participants
[newParticipantsArray addObject:PFUser.currentUser.username];
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query getObjectInBackgroundWithId:self.ObjectID
block:^(PFObject *Event, NSError *error) {
Event[#"Participants"] = newParticipantsArray;
[Event incrementKey:#"Vacants" byAmount:[NSNumber numberWithInt:-1]];
[Event saveInBackground];
}];
}else{ // STEP 5
for(int i=0;i<objects.count;i++) {
[newParticipantsArray addObject:[[objects objectAtIndex:i] valueForKey:#"Participants"]];
}
[newParticipantsArray addObject:PFUser.currentUser.username];
NSLog(#"Part to upload %#", newParticipantsArray);
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query getObjectInBackgroundWithId:self.ObjectID
block:^(PFObject *Event, NSError *error) {
Event[#"Participants"] = newParticipantsArray;
[Event incrementKey:#"Vacants" byAmount:[NSNumber numberWithInt:-1]];
[Event saveInBackground];
}];
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
This is how the method works:
Create a PFQuery object
Query the Participants Class for an specific ObjectId
If no error, then we create a NSMutable array
If no participants are in Parse then we insert the current user as participant.
Else, insert all participants in the mutable array and add currentuser at the end of the array.
Then upload it again to Parse
My problem is in step 5:
When I perform the tasks in the else, the column in Parse looks like this :
[["Participant 1"],"Participant 2"]
But I would like to have it like this:
["Participant 1","Participant 2"]
What I have tried:
I tried things like putting the arrays like this. [newParticipantsArray addObject:[[objects objectAtIndex:i] valueForKey:#"Participants"]]; and similar combinations, of course without luck.
It’s hard to say for sure since I can’t see the structure of your data but are you sure the value held in
[[objects objectAtIndex:i] valueForKey: #“Participants”]
Is a single user and not itself an array of users? The plural key “participants” seems to suggest it’s an array of users which would also explain the result you’re getting.
If in fact the value returned for the "Participants" key is an array, you can add the objects in it to your mutable array by doing the following:
NSArray* participants = [[objects objectAtIndex:i] valueForKey:#"Participants"]
[newParticipantsArray addObjectsInArray:participants];
This uses the addObjectsInArray: method of NSMutableArray to add the objects from the old array into the new one.
I have a Follower class where stores all following/follower relations of my app. However, when I was trying to retrieve the pointer of each PFUser, I can't get the attributes of each PFUser. Here is my code
PFQuery *query = [PFQuery queryWithClassName:#"Follower"];
[query whereKey:#"from" equalTo:[PFUser currentUser]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
for(PFObject *o in objects)
{
PFUser *otherUser = (PFUser *)[o objectForKey:#"to"];
NSLog(#"%#",otherUser);
NSLog(#"%#",otherUser.username);
NSString *nickName = otherUser[#"nickName"];
cell.friendNameLabel.text = nickName;
NSLog(#"%#", otherUser[#"nickName"]);
//cell.friendUsrnameLabel.text = otherUser.username;
PFFile *imgFile = otherUser[#"profilePhoto"];
profileView.file = imgFile;
[profileView loadInBackground];
}
}
else
{
NSLog(#"error");
}
}];
when I tried to print every user, here is what i got from the console:
<PFUser: 0x7fc102ec9f70, objectId: GiOIGiNHjK, localId: (null)> {
}
so it didn't find the attributes of each user. Anyone knows the solution? Thanks.
Try to add this line before executing the query.
[query includeKey:#"to"];
I'm building an application on Parse.com's backend for iOS that has simple follower / following logic to it. I.e. I want the user to be able to find other users and follow their profiles. I can currently retrieve all of the users in the database using a general PFQuery. Tapping on a users profile image "follows" that person. The data is set up so that an array called isFollowing has a unique object added to it with each new person that the user chooses to follow. It's adding it by the users objectId.
However, here's where my bump in the road is; for a separate screen I only want to return the number of people I, as a user, am following. This is the query to access the data:
- (void)viewDidAppear:(BOOL)animated
{
PFQuery *followingQuery = [PFUser query];
[followingQuery whereKey:#"objectId" equalTo:[PFUser currentUser].objectId];
[followingQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
NSLog(#"User test: %#", [objects valueForKey:#"isFollowing"]);
PFQuery *imagesQuery = [PFUser query];
[imagesQuery whereKey:#"objectId" containedIn:[objects valueForKey:#"isFollowing"]];
[imagesQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
NSLog(#"Username? %#", [objects valueForKey:#"username"]);
}
else
{
NSLog(#"Something went wrong. %#", error);
}
}];
}
else
{
NSLog(#"Something went wrong: %#", error);
}
}];
[super viewDidAppear:animated];
}
Currently, user test: %# gives the output:
2014-07-28 10:17:58.537 YouStreamSport[11276:60b] User test: (
(
bHul1vkkmB,
brsN8PRUBO
)
)
However, when I run objects.count it's returning one object. Because of this I'm unable to iterate through the array object to find and return only the proper profile images. Since the array object is returning as 1, but there are 2 objects in the array itself, how can I access the items in that array? Any attempts to access using [objectAtIndex: ...] result in a crash.
Thanks for the input in advance.
I wasn't sure how to access a single item in an array within an array, but thanks to the help of #Droppy, I was able to solve the problem. This is the code I am now using:
- (void)viewDidAppear:(BOOL)animated
{
PFQuery *followingQuery = [PFUser query];
[followingQuery whereKey:#"objectId" equalTo:[PFUser currentUser].objectId];
[followingQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
self.array = [objects valueForKey:#"isFollowing"];
NSLog(#"User test: %#", self.array);
for (int i = 0; i <= self.array.count; i++)
{
NSLog(#"User %d: %#", i, [[[objects valueForKey:#"isFollowing"] objectAtIndex:0] objectAtIndex:i]);
}
}
else
{
NSLog(#"Something went wrong: %#", error);
}
}];
[super viewDidAppear:animated];
}
The resulting output is as follows:
2014-07-28 10:53:16.155 appName[11416:60b] User 0: bHul1vkkmB
2014-07-28 10:53:16.156 appName[11416:60b] User 1: brsN8PRUBO
Thank you!
As written you will only display one objects username. Instead of trying to access them by index try iterating through the results like below. I'd also recommend not using the variable objects for both the inner and outer query. Try this out:
[imagesQuery findObjectsInBackgroundWithBlock:^(NSArray *myObjects, NSError *error)
{
if (!error){
if (myObjects.count) {
for (PFObject *item in myObjects){
NSLog(#"Username: %#", [item valueForKey:#"isFollowing"]);
}
}
}else{
NSLog(#"Something went wrong. %#", error);
}
}];
My PFQuery returns the following description.I am trying to fetch the objectId of the class
YouQuestions.For eg: in the below description Ovx3B1TnaC is the objectId for the first index of quesAray. But I have no idea on how to fetch it.
Printing description of quesArray:
<__NSArrayM 0xe1198f0>(
<YouQuestions:OVx3BlTnaC:(null)> {
askedUser = "<PFUser:XGvZsNyg9p>";
attachedImage = "<PFFile: 0xb4c9d20>";
category = Business;
geoLocation = "<PFGeoPoint: 0xb4c9ea0>";
question = "Who is kaka?";
thumbImage = "<PFFile: 0xb4c9dd0>";
},
This is how I did but returned nil
PFQuery *fetchTimeLine = [PFQuery queryWithClassName:#"YouQuestions"];
[fetchTimeLine whereKeyExists:#"objectId"];
[fetchTimeLine findObjectsInBackgroundWithBlock:^(NSArray *quesArray, NSError *error)
{
for (int i =0; i<quesArray.count; i++)
{
PFObject *obj = [quesArray[i] objectForKey:#"objectId"];
[searchobjectIDsArray addObject:obj.objectId];
}
}];
EDIT:
I fixed it like this
for (PFObject *object in quesArray) {
NSLog(#"%#", object.objectId);
}
to get the array of ids:
NSArray *oids = [quesArray valueForKeyPath:#"objectId"];
I am trying to filter and sort an NSMutableArray containing a list of Chat Messages. I am trying to get the Last Message of a conversation between 2 users. For example if user1 has 2 different conversations with 2 separate users, I want to get the last message of each of those conversations. I am using Parse.com as backend and this how I saved & retrieved the messages.
Saving the Messages
PFUser *user = [[PFUser currentUser] objectForKey:#"displayName"];
PFObject *newMessage = [PFObject objectWithClassName:#"Messages"];
[newMessage setObject:messageStr forKey:#"body"];
[newMessage setObject:self.mySelectedUser forKey:#"toUser"];
[newMessage setObject:user forKey:#"fromUser"];
[newMessage saveInBackground];
myMessageField.text = #"";
[self getTheNewMessages];
[self.myTView reloadData];
Retrieving The Messages
-(void)GetmyNewMessages
{
PFQuery *query1 = [PFQuery queryWithClassName:#"Messages"];
[query1 whereKey:#"toUser" equalTo:[[PFUser currentUser] objectForKey:#"displayName"]];
[query1 whereKeyExists:#"date"];
PFQuery *query2 = [PFQuery queryWithClassName:#"Messages"];
[query2 whereKey:#"fromUser" equalTo:[[PFUser currentUser] objectForKey:#"displayName"]];
[query2 whereKeyExists:#"date"];
PFQuery *query = [PFQuery orQueryWithSubqueries:[NSArray arrayWithObjects:query1, query2, nil]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"Successfully retrieved %d chats.", objects.count);
[premessagesList removeAllObjects];
[premessagesList addObject:objects];
} else {
//Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
NSLog of the NSMutableArray (premessageList)
( "<Messages:aS8tVIlsHc:(null)> {\n
body = hi;\n fromUser = cnn;\n toUser =FNC;\n
date = \"2012-09-19 02:40:29 +0000\";\n}",
"<Messages:CPCa6VBmf7:(null)> {\n
body = hello;\n fromUser = FNC;\n toUser =cnn;\n
date = \"2012-09-20 05:06:05 +0000\";\n}",
"<Messages:Jz1cILt18Y:(null)> {\n
body = whatsgood;\n fromUser = sleepy;\n toUser =cnn;\n
date =\"2012-09-20 05:06:05 +0000\";\n}",
"<Messages:lXretmE1uK:(null)> {\n
body = lol;\n fromUser = cnn;\n toUser =sleepy;\n
date =\"2012-09-20 05:13:16 +0000\";\n}",
I tried to use NSSortDescriptor and NSPredicate but I got an empty tableview.
In this type of problem, I would use some variables and fast iteration to slog through the info and get what you need:
id lastChat = ni;
... temps
for(OneChat in allChats) {
do tests and set variables
}
Now I know the last chat.
PS: I decided not to post this, but when I saw after a long time no one had responded felt it was better than nothing. This is how I would solve this.
You could limit the results and sort through the PFQuery itself like this:
[query1 orderByDescending:#"createdAt"];
query1.limit = 1;
[query2 orderByDescending:#"createdAt"];
query2.limit = 1;