Search code examples
iosobjective-cparse-platformpfquerypfuser

Querying interrogation with PFUser and Friendship restriction


I have my app where users write opinions and only their friends can see them in the timeline and comment it (In a UITableViewController subclass called "OpTimelineTableViewController"). But I have an interrogation on how to do this restriction query properly even that I tried solutions before with no more results... (I begin to introduce you my data model):

"User" table (is the built-in class provided by Parse)

"Opinion" table:

objectId;

senderId; Pointer User table

content; String

updatedAt; (provided by default)

createdAt; (provided by default)

"Friends" table:

friendId1 = Pointer User table

friendId2 = Pointer User table

status = String who can take "Confirm", "Pending", or "Denied"

updatedAt = (provided by default)

createdAt = (provided by default)

Now this is the major important parts of code that I tried:

- (void)loadOpinions {

    PFQuery *opinionQuery = [PFQuery queryWithClassName:@"Opinion"];
    [opinionQuery orderByDescending:@"createdAt"];

    [opinionQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (!error) {

// Array declared as property in the ".h" that contains Opinion objects

            self.opinionArray = [[NSArray alloc] initWithArray:objects];
        }

        [self.tableView reloadData];
        [self.refreshControl endRefreshing];
  }];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.opinionArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    OpinionTimelineCell *opCell = [tableView dequeueReusableCellWithIdentifier:@"OpTimelineCell" forIndexPath:indexPath];

// self.tempOpObj is an instance of PFObject declared in the ".h" that contains opinion object (for the appropriate index) contained in the opinionArray

    self.tempOpObj = [self.opinionArray objectAtIndex:indexPath.row];

// Now I query "User" table to retrieve all users that have posted Opinions:

    PFQuery *UserOpinionQuery = [PFUser query];

// I do a restriction between users that are contained in the "Opinion" table:

    [UserOpinionQuery whereKey:@"objectId" equalTo:[[self.tempOpObj objectForKey:@"senderId"]objectId]];

    [UserOpinionQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (!error) {

// "userOpInfo" is an instance of PFUser declared in the ".h" that contains the last of object retrieved in "objects":

            self.userOpInfo = [objects lastObject];

            opCell.opinionUsername.text = self.userOpInfo.username;
          }
       }];

    opCell.opinionContent.text = [self.tempOpObj objectForKey:@"content"];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"mm-DD-yyyy";
    opCell.opinionDate.text = [dateFormatter stringFromDate:self.tempOpObj.createdAt];

    [opCell setSelectionStyle:UITableViewCellSelectionStyleNone];

// ? Query to restrict visible Opinion posts only if users are a current user friend:

    PFQuery *restrictFriendQuery = [PFQuery queryWithClassName:@"Friends"];
    [restrictFriendQuery whereKey:@"friendId1" equalTo:[PFUser currentUser]];
    [restrictFriendQuery whereKey:@"friendId2" equalTo:[self.userOpInfo objectId]];
    [restrictFriendQuery whereKey:@"status" equalTo:@"Confirm"];

// Is that way the best ??

    [restrictFriendQuery findObjects];

    return opCell;
}

My problem is at that point: how to know what query I do before the others, by knowing that the number of cells is depending of the number of Opinions contained in the opinionArray, or just simply: how to query by restricting displayed opinions only from current User's friends ?

(Note: I precise that I have implemented the method [self.performSelector(loadOpinions)....... in viewDidLoad for information)

My code does not appears to be clear I'm all Ok, this is why I do not find an easy way to do it

Does anyone could help for how to fix that ?


Solution

  • I'd use your Friends table just to help manage the request and approval process. I'd use cloud code such that when a friendship is approved the friend is added into a relationship on the User table.

    By doing this you will be able to get a query from the current user which contains all of their friends. This can be used with a query on Opinions to restrict the results to those rows created by a friend user.