I have a TableView subclassed as a PFQueryTableViewController and I want to know how I can retrieve an inventory of users post from Parse. I'm having trouble receiving the users data and displaying with my code. Is there something I need to edit in my queryForTable, change in parse or change in my code?
Here is my ProfileViewController:
import UIKit
import Parse
import ParseUI
class ProfileViewController: PFQueryTableViewController{
var profilePosts:NSMutableArray! = NSMutableArray()
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.parseClassName = "Test"
self.textKey = "postMessage"
self.pullToRefreshEnabled = true
self.objectsPerPage = 200
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func queryForTable() -> PFQuery {
let query = PFQuery(className: "Test")
query.whereKey("username", equalTo: PFUser.currentUser()!)
query.limit = 200;
return query
}
// MARK: - Table view data source
override func objectAtIndexPath(indexPath: NSIndexPath!) -> PFObject? {
var obj : PFObject? = nil
if(indexPath.row < self.objects!.count){
obj = self.objects![indexPath.row] as? PFObject
}
return obj
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return profilePosts.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath?, object:PFObject!) -> PFTableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PCell", forIndexPath: indexPath!) as! ProfileCell
if let profilePost : PFObject = self.profilePosts.objectAtIndex(indexPath!.row) as! PFObject {
cell.NameProfile.text = object["account"] as? String
cell.messageProfile.text = object["postMessage"] as? String
let dateUpdated = object.createdAt! as NSDate
let dateFormat = NSDateFormatter()
dateFormat.dateFormat = "MMM d, h:mm a"
cell.timeProfile.text = NSString(format: "%@", dateFormat.stringFromDate(dateUpdated)) as String
cell.messageProfile.numberOfLines = 0
let likeScore = object[("count")] as! Int
cell.likeScoreProfile.text = "\(likeScore)"
let replyscore = object["replies"] as! Int
cell.replyScoreProfile.text = "\(replyscore) replies"
cell.messageProfile.text = profilePost.objectForKey("postMessage") as? String
if let profilePic = object["profilePhoto"] as? PFFile {
let imageView = cell.profilePhoto as PFImageView
imageView.image = UIImage(named: "profileImg")
imageView.file = profilePic
imageView.loadInBackground(nil)
}
return cell
}
You never assign your profilePosts
to the objects
that are returned from parse. You have two options for fixing this. One is to just stick with the default parse implementation of objects which allows you to use objects
whenever you need one of your database objects. The other is to stick with your profilePosts
array and assign it in objectsDidLoad
which would prevent you from having to change any code except for that. Otherwise in your methods like numberOfRowsInSection
you would need to return objects!.count
instead.
In the case that you decide to use your own array of profilePosts
you'll want to do this:
import UIKit
import Parse
import ParseUI
class ProfileViewController: PFQueryTableViewController{
var profilePosts:NSMutableArray! = NSMutableArray()
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.parseClassName = "Test"
self.textKey = "postMessage"
self.pullToRefreshEnabled = true
self.objectsPerPage = 200
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func objectsDidLoad(error: NSError?) {
super.objectsDidLoad(error)
profilePosts = NSMutableArray(array: objects!)
self.tableView.reloadData()
}
override func queryForTable() -> PFQuery {
let query = PFQuery(className: "Test")
query.whereKey("username", equalTo: PFUser.currentUser()!.username)
query.limit = 200;
return query
}
// MARK: - Table view data source
override func objectAtIndexPath(indexPath: NSIndexPath!) -> PFObject? {
var obj : PFObject? = nil
if(indexPath.row < self.profilePosts.count){
obj = self.profilePosts[indexPath.row] as? PFObject
}
return obj
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return profilePosts.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath?) -> PFTableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PCell", forIndexPath: indexPath!) as! ProfileCell
if let object : PFObject = self.profilePosts.objectAtIndex(indexPath!.row) as? PFObject {
cell.NameProfile.text = object["account"] as? String
cell.messageProfile.text = object["postMessage"] as? String
let dateUpdated = object.createdAt! as NSDate
let dateFormat = NSDateFormatter()
dateFormat.dateFormat = "MMM d, h:mm a"
cell.timeProfile.text = NSString(format: "%@", dateFormat.stringFromDate(dateUpdated)) as String
cell.messageProfile.numberOfLines = 0
let likeScore = object[("count")] as! Int
cell.likeScoreProfile.text = "\(likeScore)"
let replyscore = object["replies"] as! Int
cell.replyScoreProfile.text = "\(replyscore) replies"
cell.messageProfile.text = profilePost.objectForKey("postMessage") as? String
if let profilePic = object["profilePhoto"] as? PFFile {
let imageView = cell.profilePhoto as PFImageView
imageView.image = UIImage(named: "profileImg")
imageView.file = profilePic
imageView.loadInBackground(nil)
}
return cell
}
Notice how I changed cellForRowAtIndexPath
to use the object you were getting from profilePosts
and then how I overrode objectsDidLoad
and assigned the PFQueryTableView
objects
property to your profilePosts
array. One reason you may want to do this is because by having your own managed copy of the Parse objects you can perform things like insertion or deletion with animation, which the regular objects
property does not allow you to do. Hopefully this helps you out, let me know if you have more questions.
EDIT 2
In light of your comment about your more specific question, I would suggest that you edit your original question to specify that you are asking about how to get just the current user's objects, and not about which implementation to use. I am leaving that code above in there however, because the queryForTable
method has been modified to show what you need to do to meet your query demands. It also does show those that come looking how to properly retrieve objects if they are having issues.