Update bool value in Parse for iOS - ios

I am using Parse for iOS. https://www.parse.com/docs/downloads/
However, i have faced difficulties for updating the bool value at specified objectID as shown in this picture.
http://tinypic.com/view.php?pic=8y4zt2&s=5
I can add new row by setting like this. But, now, I want to update the bool value at specified objectID. I would like to know how to do.
PFObject *gameScore = [PFObject objectWithClassName:#"GameScore"];
[gameScore setObject:[NSNumber numberWithBool:NO] forKey:#"cheatMode"];

I have found a way to do.
PFQuery *query = [PFQuery queryWithClassName:#"test"];
[query whereKey:#"objectId" equalTo:objectIDForReport];
[query getFirstObjectInBackgroundWithBlock:^(PFObject * reportStatus, NSError *error) {
if (!error) {
// Found UserStats
[reportStatus setObject:[NSNumber numberWithBool:YES] forKey:#"report"];
// Save
[reportStatus saveInBackground];
} else {
// Did not find any UserStats for the current user
NSLog(#"Error: %#", error);
}
}];

Related

Why is my NSMutable not being populated correctly when inserting objects from another NSArray?

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.

Query the current users information

This is using Parse btw.
I have information saved into the users class using this code here
-(IBAction)saveButtonAction:(id)sender {
PFUser *currentUserSave = [PFUser currentUser];
userBioString = userBio.text;
genderFieldString = genderField.text;
ageFieldString = ageField.text;
currentUserSave[#"userBioParse"] = userBioString;
currentUserSave[#"userGenderParse"] = genderFieldString;
currentUserSave[#"ageFieldParse"] = ageFieldString;
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] fetch];
Now I am trying to call back the information using a query. I researched how to do it and this is my result as of now.
-(IBAction) userProfileQuery {
NSString *bioQueryString = [[PFUser currentUser] objectForKey:#"userBioParse"];
userBio.text = bioQueryString;
NSString *ageQueryString = [[PFUser currentUser] objectForKey:#"ageFieldParse"];
ageField.text = ageQueryString;
NSString *genderQueryString = [[PFUser currentUser] objectForKey:#"genderFieldParse"];
genderField.text = genderQueryString;
the information is being saved into the users class successfully. I am just unsure how to retrieve it... Thanks in advance for any feedback!
There are more than one way to get the currentUsers information in parse. Try this code out. Its the most complicated one, but reading the code its easier to understand what you are doning.
PFQuery *query= [PFUser query];
[query whereKey:#"username" equalTo:[[PFUser currentUser]username]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error){
if (!error) {
userBio.text = [object valueForKey:#"userBioParse"];
ageField.text = [object valueForKey:#"ageFieldParse"];
genderField.text = [object valueForKey:#"genderFieldParse"];
}
else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
If you are doing it the way you are doing it, try, thats a litte bit of a shortcut:
PFUser *user = [[PFUser currentUser];
userBio.text = user.userBioParse;
Parse already gives you most of the code for currentUser. And the fastest way to get currentUser information that parse offers is:
userBio.text = currentUser.userBioParse;

(parse) getting error when updating pfobject

However simple it may be, I am still struggling to update PFObject data with
-(IBAction)postMessageTapped:(id)sender{
[self hideTextField:_messageTextField];
NSMutableArray *myNewMessageArray=[[NSMutableArray alloc]init];
[myNewMessageArray insertObject:_messageTextField.text atIndex:0];
[myNewMessageArray insertObject:[PFUser currentUser] atIndex:1];
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query getObjectInBackgroundWithId:currentId block:^(PFObject *object, NSError *error) {
object[messagingArray] = myNewMessageArray;
[object saveInBackground];
}];
}
The intent is to get message string from text field and current user name, and put that into an array which then updates the array that exists on the parse database. However,
Cannot do a comparison query for type: (null)
comes up when the user taps the button that posts the message.
Does anyone have a possible solution?
Edit:
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query whereKey:#"location" nearGeoPoint:locationOfSelectedPin];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!objects) {
NSLog(#"The getFirstObject request failed.");
} else {
for(PFObject *objectTest in objects){
NSLog(#"Successfully retrieved the object.");
objectTest[#"messagingArray"]=myNewMessageArray;
[objectTest saveInBackground];
}
}
}];
I have also tried using this to update my data, 'successfully retrieved object' gets printed 3 times, but then that is followed by three lines of 'error, object not found for update'.
Check where you are setting objectId - this error means it cannot get the object because you are passing a nil value to the database for lookup.
Here's a bit of code to handle the exception:
if (!currentId) {
NSLog(#"Your currentId object is nil! Check your assignment.");
}
else {
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query getObjectInBackgroundWithId:currentId block:^(PFObject *object, NSError *error) {
object[messagingArray] = myNewMessageArray;
[object saveInBackground];
}];
}

Query PFUser currentUser for a custom field

I am using the parse framework and would like to know how I can query a column that is located in the PFUser table.
Here is some example code:
//Adds athlete_id column to roster table
PFObject *roster = [PFObject objectWithClassName:#"Roster"];
roster[#"athlete_id"] = answer;
[roster save];
//Adds the rosters objectId to an array (athlete_id) in the User table.
PFUser *currentUser = [PFUser currentUser];
[currentUser addObject:roster.objectId forKey:#"athlete_id"];
[currentUser saveInBackground];
With the above code end up getting an array of objectsID's within the User class in a column named "athlete_id".
Im having a problem actually retrieving this array from the User class. Here is how I am attempting to get the array from the user:
FQuery *query = [PFUser query];;
[query whereKey:#"username" equalTo:[PFUser currentUser].username];
[query whereKeyExists:#"athelete_id"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"athlete %#", objects);
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
I want to grab the array that is contained in athlete_id column for the current user, but the objects array is empty on this query.
You don't need a query.
Just do this:
NSString *athleteId = [[PFUser currentUser] objectForKey:#"athelete_id"];
NSLog(#"The athlete id is %#", athleteId);

Parse Set Object To UILabel

So this is my first time working with parse I have simple application which creates a user and allows them to sign in. I'm currently working on something that will allow them to fill in details about themselves using PFObjects, I don't have a problem with that. My issue is I need to get user specific data print out on an UILabel.
Here's my code creating a PFObject this works fine:
- (IBAction)saveProfile:(id)sender {
PFObject *profile = [PFObject objectWithClassName:#"Profile"];
[profile setObject: self.name.text forKey:#"name"];
[profile setObject:[PFUser currentUser] forKey:#"author"];
[profile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(#"No Error");
}else NSLog(#"Yeah you got an error bro");
}];
}
Here's what I'm having an issue with my PFQuery:
PFQuery *query = [PFQuery queryWithClassName:#"Profile"];
[query whereKey:#"name" equalTo:[PFUser currentUser]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSLog(#"Success");
self.nameLabel.text = [NSString stringWithFormat:#"%#", query];
}
else {
NSLog(#"Fail");
}
}];
}
So basicly I want the user to enter their name have it save, and have that specific user's name print out on a label. This is as far as I got so, if you have any suggestions I'm all ears. Thanks!
Updated:
PFQuery *query = [PFQuery queryWithClassName:#"Profile"];
[query whereKey:#"author" equalTo:[PFUser currentUser]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSLog(#"Success");
self.nameLabel.text = object[#"name"];
}
else {
NSLog(#"Fails");
}
}];
}
Looks like you're setting the PFObject "name" key to self.name.text, but in your PFQuery you're querying the class and asking for values where "name" is equal to [PFUser currentUser]. You're setting the value one way then using a completely different value in an attempt to query the object; so getFirstObjectInBackgroundWithBlock isn't returning an object since there's no Profile object where "name" equals [PFUser currentUser].
I think you're confusing your "name" and "author" properties...
Edit (in response to your comment):
OK, so in saveProfile: you're creating a PFObject where you're setting "name" to the name string and "author" to the user's PFUser object. When you're using whereKey: to perform a query on this class in an effort to retrieve the object using getFirstObjectInBackgroundWithBlock:, the result returned to you will be the full first PFObject where the object associated with the key is the one specified in the whereKey: criteria. So you don't have to specify which key of the PFObject you want to read before performing getFirstObjectInBackgroundWithBlock:. The query returns the whole object -- name, author, etc.
So in order to access the returned PFObject's "name" within the query block, change:
self.nameLabel.text = [NSString stringWithFormat:#"%#", query];
to (dispatch_aync added to force the label change onto the main thread):
dispatch_async(dispatch_get_main_queue(),^{
self.nameLabel.text = object[#"name"];
});
This line
[query whereKey:#"name" equalTo:[PFUser currentUser]];
only works if the "name" column is a pointer or relation to the User class. If it is the username you're after, you need to use
[query whereKey:#"name" equalTo:[PFUser currentUser][#"username"]];
But why are you querying for the object you just saved?
Your last, updated example should work for your need.
You could fire up a query like the one below
PFQuery *query = [PFQuery queryWithClassName:#"Profile"];
NSString *nameStr = [NSString stringWithFormat:#"%#",[[PFUser currentUser]objectForKey:#"name"]];
[query whereKey:#"name" containsString:nameStr];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error)
{
if (!error)
{
/*object contains all columns and you need only key to obtain value*/
nameLabel = [NSString stringWithFormat:#"%#",object[#"job"];
.
.
.
}
else
{
NSLog(#"Error: %#", [error localizedDescription]);
}
}];
Now you will have object of current user along with its all details. Also you could do a thing, i.e., At time of user filling up profile details save it in a dictionary as below :
NSDictionary *signupDetail = [NSDictionary dictionaryWithObjectsAndKeys:self.userRegisterTextField.text, #"username",
self.nameTextField.text, #"Name",
[ResponseDict objectForKey:#"sessionToken"] ,#"sessionToken",
[ResponseDict objectForKey:#"objectId"], #"objectId",
nil];
//ResponseDict is dictionary you get in response for successful signup.
Then you could store it using [NSUserDefaults standardUserDefaults] so you will have all info of user at one place and call it wherever needed.

Resources