Search code examples
iosiphoneswiftparse-platformpfquerytableviewcontrolle

Why are the same comments showing for different user posts? (iOS, Swift, Parse)


Working on a social iPhone app using Swift (with a Storyboard) and Parse where users can create posts and comment on posts similar to the Facebook iOS app and other social network apps.

The app has an initial, master Home Feed page (which displays user posts) and a detail Reply page (which is supposed to display the comments for a particular post that was selected but is showing the same replies for different posts). Both use the PFTableViewController class and each have their own PFTableViewCell implemented in separate swift files as the prototype cells.

When a user taps on ANY post cell in the Home Feed page, it navigates to the Reply page but shows all existing comments (as well as every new comment) for the post. I am trying to have only the comments for a specific post show when the user selects a particular post from the Home Feed page.

Any idea why this is happening? I greatly appreciate your time and help!

Home Feed page:

class HomeTableVC: PFQueryTableViewController,CLLocationManagerDelegate {

  var posts: NSMutableArray! = NSMutableArray()

  override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
    return posts.count
  }

  override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
  }

  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    self.performSegueWithIdentifier("showReplyViewController", sender: self)

  }

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?, object: PFObject!) -> PFTableViewCell? {

    let cell = tableView!.dequeueReusableCellWithIdentifier("PostCell", forIndexPath: indexPath!) as! PostTableCell


    if let userPost : PFObject = self.posts.objectAtIndex(indexPath!.row) as! PFObject {

        cell.name.text = object["userName"] as? String
        cell.message.text = object["postMessage"] as? String
        let dateUpdated = object.createdAt! as NSDate
        let dateFormat = NSDateFormatter()
        dateFormat.dateFormat = "h:mm a"

        cell.dateTime.text =  NSString(format: "%@", dateFormat.stringFromDate(dateUpdated)) as String
        cell.message.numberOfLines = 0

        cell.message.text = userPost.objectForKey("postMessage") as? String
    }        

    return cell
}

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      if (segue.identifier == "showReplyViewController") {

        let indexPath = self.tableView.indexPathForSelectedRow

        let postObject = self.objects![indexPath!.row] as! PFObject

        //postObject (on LHS) is the PFObject declared in ResponseViewController
        if let destinationVC = segue.destinationViewController as? ReplyTableViewController {

            destinationVC.postObject = postObject
        }


      }
   }
}

Reply page:

class ReplyTableViewController: PFQueryTableViewController {

var postObject: PFObject?

var replies: NSMutableArray! = NSMutableArray()

override func viewDidAppear(animated: Bool) {

    super.viewDidAppear(animated)

    replies = NSMutableArray()

    var replyQuery = PFQuery(className: "Reply")

    replyQuery.addAscendingOrder("createdAt")

    replyQuery.findObjectsInBackgroundWithBlock {
    (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {

            for object in objects! {
                let reply: PFObject = object as! PFObject
                self.replies.addObject(reply)
            }

            let repliesArray: NSArray = self.replies.reverseObjectEnumerator().allObjects

            self.replies = NSMutableArray(array: repliesArray)

            self.tableView.reloadData()

        }
    }

}

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {

    return replies.count
}

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?, object: PFObject!) -> PFTableViewCell? {

  let cell = tableView!.dequeueReusableCellWithIdentifier("replyCell", forIndexPath: indexPath!) as! ReplyTableViewCell

  let replyObject: PFObject = self.replies.objectAtIndex(indexPath!.row) as! PFObject

  cell.replyMessageLabel.text = replyObject.objectForKey("replyMessage") as? String

  var queryUser: PFQuery = PFUser.query()!
    queryUser.whereKey("objectId", equalTo: (replyObject.objectForKey("replyUser")?.objectId)!)

  queryUser.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {

            let user: PFUser = (objects! as NSArray).lastObject as! PFUser
            cell.replyAuthorLabel.text = user.username
        }
  }

  return cell
}
}

Solution

  • I found a solution to my own problem!

    I have updated the Reply page to use UITableViewController instead of PFTableViewController and updated the storyboard correspondingly (I made the necessary changes in the code and in the Storyboard to comply with the constraints of UITableViewController, etc).

    I implemented a PFQuery with the appropriate constraints to fetch all the replies for a given post (only) by writing something similar to the following:

    query.whereKey("parent", equalTo: aPost)
    
    // Finds objects *asynchronously* and call the given block with the results.
    query.findObjectsInBackgroundWithBlock {
      (objects: [AnyObject]?, error: NSError?) -> Void in
    
       // if there is no error, for each object in `objects`,
       // assign the given object to a PFObject
       // add the object to an array that will store all of the applicable replies for the post
       // ...
    }