I think I'm overcomplicating this scenario. I'm working through a join table in a many to many situation.
If I find a join, I want to delete it, if I don't find one, I want to add it.
Adding a new join works fine. I can't figure how to delete ..
This is my code. If anyone sees anything wrong - or a better way to do this, please advise.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%s", __FUNCTION__);
//Create query for all current user objects
PFQuery *query = [PFQuery queryWithClassName:#"DDPeopleJoin"];
[query whereKey:#"parseUser" equalTo:[PFUser currentUser]];
[query whereKey:#"serviceKey" equalTo:[currentService valueForKey:#"serviceKey"]];
[query whereKey:#"personKey" equalTo:[currentPerson valueForKey:#"personKey"]];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
// Run the query - if there is an object delete it otherwise, go to JoinPeople
allDeadPeople = [NSMutableArray new];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
if (!objects) {
NSLog(#"New Person");
[self joinPeople];
return;
}
NSLog(#"Found a match, erase them");
for (PFObject *object in objects) {
[object deleteInBackground];
}
[self refreshJoins:self];
}
}];
}
Firstly, instead of using enumerate block to delete each object, you can use the following:
[PFObject deleteAllInBackground:objects];
Secondly, You might get trouble with [self refreshJoins:self coz it will run before all object can be deleted. You should put that in the -deleteInBackground:block to make sure [self refreshJoins:self]` works properly
Related
I am working on a little app with parse.com. I want to download all objects from a column (Array) called "Firstname". I found some code, but when I log "object" it shows the class completely:
PFQuery *query = [PFQuery queryWithClassName:#"Name"];
[query selectKeys:#[#"Firstname"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSLog("%#", objects);
}];
Edit:
PFQuery *query = [PFQuery queryWithClassName:#"Name"];
[query selectKeys:#[#"Firstname"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
self.FirstnameArray = [objects valueForKey:#"Firstname"];
NSLog(#"%#", self.FirstnameArray);
[self.myTableView reloadData];
}];
A query always returns objects of the class associated with the query. Using selectKeys just limits the data that comes back.
You can extract an array of just the values from the returned array with:
NSArray *values = [objects valueForKey:#"Firstname"]
Thats normal, you will get back the whole object - aka a row from that class you are performing the query on. If I recall correct, SelectKey will return any associated object - ie a relation object. So in your case you do not need to use select.
I have a table called "UserSnapshot" on Parse and of course you get the objectID's as you populate the table.
However, when I query the table for an object from my app I wont have the object ID's but I will have their "UserCode". I have been playing with something like this.
PFQuery *userProfile = [PFQuery queryWithClassName:#"UserSnapshot"];
[userProfile whereKey:#"Code" equalTo:_Code];
[userProfile getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!object) {
// Did not find PFObject
// not executed
} else {
// Found PFObject
// also not executed....huh?
}
}];
But nothing happens. Neither the if or the else is entered. Am I missing something?
Thanks
Does anything print out in the log/console? It's possible that you didn't set your keys properly when initializing Parse in your App Delegate.
PFQuery *userProfile = [PFQuery queryWithClassName:#"UserSnapshot"];
[userProfile whereKey:#"Code" equalTo:_Code];
PFObject *object = [userProfile getFirstObject];
Works!
How would I go about displaying a list of all users in the parse.com database in a tableview and then when they click on each table, display that particular user's information.
All I know is that in order to query the users I must use:
PFQuery *query = [PFUser query];
Thank you in advance and any help is much appreciated.
You're really asking a specific question about Parse queries, but it seems like you don't understand queries in general, so just start with a general query against Parse:
PFQuery *query = [PFQuery queryWithClassName:#"_User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
// Something went wrong
} else {
// objects is an array of PFObject containing your results
}
}];
As you figured out, you can also do a user query by making that first line:
PFQuery *query = [PFUser query];
The rest is the same.
Lyndsey Scott is right, this is basic stuff in the docs. I'm posting this here because of the one "gotcha" which is the class name (_User instead of User) if you use the first method.
What you generally will do is call [myTableView reloadData] inside the success block since you now have an array of users. In your didSelectCellAtIndexPath: perform a seque with a new viewcontroller, and in your prepareForSegue method, pass the user object to your pushed view controller so it knows what user to show.
I assume you know how to use table view. So I'll implement it this way:
1.create a property
#property (nonatomic) NSArray *users;
2.In viewDidAppear execute the query:
PFQuery *query = [PFUser query];
[query setLimit:1000];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.users = objects;
[self.tableView reloadData];
}
}];
3.You need to implement table view code, the most important is cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"userCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
PFUser *user = self.users[indexPath.row];
cell.textLabel.text = user.username;
return cell;
}
Beside that you also need all of the required table view's data source code to tell it the number of cell. If you'll need some help with that just tell.
I'm querying relation data on parse and I would like the objects to come back ordered by the date they were created. I've had this method work before but haven't been able to get an ordered query using relational data. The query return is in a random order. Thanks in advance! Here's my code:
PFQuery *postQuery = [PFQuery queryWithClassName:#"Post"];
[roomQuery whereKey:#"name" equalTo:self.postName];
NSError *error;
//done on main thread to have data for next query
NSArray *results = [postQuery findObjects:&error];
PFObject *post;
if ([results count]) {
post = [results objectAtIndex:0];
NSLog(#"results were found");
} else {
NSLog(#"results were not found");
}
PFRelation *commentsRelation = [#"Comments"];
[commentsRelation.query orderByAscending:#"createdAt"];
[commentsRelation.query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error Fetching Comments: %#", error);
} else {
NSArray *comments = objects;
}
I'm a little confused by your code,
you create a "postQuery", and call it, but never use any of its data.
There's also a roomQuery that never seems to have been allocated, or used.
You're querying a specific post by its name. Are you controlling its name? If not, you should use id's
what is PFRelation commentsRelation = [#"Comments"];
Probably because it's just a snippet, this stuff is dealt with elsewhere; however, for my answer, I'm assuming that your "comments" field is an array of "Comment" class objects.
Option 1:
PFQuery * postQuery = [PFQuery queryWithClassName:#"Post"];
[postQuery whereKey:#"name" equalTo:self.postName];
// again, possibly an id field would be more reliable
// [postQuery whereKey:#"objectId" equalTo:self.postId];
[postQuery includeKey:#"Comments"];
PFObject * post = [postQuery getFirstObject];// no need to download all if you just want object at [0]
// this will contain your post and all of it's comments with only one api call
// unfortunately, it's not sorted, so you would have to run a sort.
NSArray * comments = [post[#"Comments"] sortedArrayUsingComparator: ^(id obj1, id obj2) {
return [obj1[#"createdAt" compare: obj2[#"createdAt"];
}];
Option 2:
Perhaps a better option is to rework your data structure and instead of associating the comments to the post, you could associate the post to the comments (as in the parse docs)
PFQuery * postQuery = [PFQuery queryWithClassName:#"Post"];
[postQuery whereKey:#"name" equalTo:self.postName];
// again, possibly an id field would be more reliable
// [postQuery whereKey:#"objectId" equalTo:self.postId];
PFQuery * commentQuery = [PFQuery queryWithClassName:#"Comment"];
[commentsQuery whereKey:#"parent" matchesQuery:postQuery]; // when creating a comment, set your post as its parent
[commentsQuery addOrderDescending:#"createdAt"]
[commentQuery findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
// comments now contains the comments for myPost
}];
Both of the above solutions avoid making extra unnecessary api calls (parse charges based on calls after all!).
Hello everyone I'm trying to merge two queries with MatchesQuery but the data on the TableView will not be displayed and gives me this error
Error: bad type for $ inquery
Does anyone know what is the error in this query? Thanks to all
- (void) retrieveFromParse {
PFQuery *Amici = [PFQuery queryWithClassName:#"Amicizie"];
[Amici whereKey:#"RICHIESTA_IN_ATTESA" equalTo:#"YES"];
PFQuery *retrievePets = [PFQuery queryWithClassName:FF_USER_CLASS];
[retrievePets whereKey:FF_USER_NOMECOGNOME matchesQuery:Amici];
[retrievePets orderByAscending:FF_USER_NOMECOGNOME];
[retrievePets findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
allObjects = [[NSMutableArray alloc] init];
for (PFObject *object in objects) {
[allObjects addObject:object];
}
}
[self.FFTableViewFindUser reloadData];
}];
}
Given that you are querying on a boolean value, you should look at this question.
Basically you need to do this:
[Amici whereKey:#"RICHIESTA_IN_ATTESA" equalTo:[NSNumber numberWithBool:YES]];
That may be all you need. If not it will get you another error message to help you get to the root of the issue.
You can add a "amiciString" column which holds the string value. Then you can do this:
[retrievePets whereKey:#"FF_USER_NOMECOGNOME" matchesKey:#"amiciString" inQuery:Amici];
Try! I hope it works!