Swift: Trying to displaying only the users data in one page - ios

I've created a profile page to display all of the users blog post. In my viewController I've used a PFQueryTableViewControllerto query the users blogs. The problem I'm having is when I run my app to see the current users blogs, I see the current users post first in the order it was created, then under I see everyone else's blogs that is coming from the className I created in Parse. The post are also repeating when I'm on this page. Is there something I need to do in my code to only show the current signed in users blogs instead of all of the post from Parse? I've pasted my code below to get a better idea.
import UIKit
import Parse
import ParseUI
class ProfileVC: PFQueryTableViewController {
var profilePage: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 = "BlogPost"
self.textKey = "blogging"
self.pullToRefreshEnabled = true
self.objectsPerPage = 200
}
override func viewDidLoad() {
super.viewDidLoad()
let user = PFObject(className:"BlogPost")
user["writer"] = PFUser.currentUser()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func objectsDidLoad(error: NSError?) {
super.objectsDidLoad(error)
profilePage = NSMutableArray(array: objects!)
self.tableView.reloadData()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let query = PFQuery(className: "BlogPost")
if let user = PFUser.currentUser() {
query.whereKey("writer", equalTo: PFUser.currentUser()!.username!)
query.addAscendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock {(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil{
for object in objects!{
let blog : PFObject = object as! PFObject
self.profilePage.addObject(blog)
}
let array : NSArray = self.profilePage.reverseObjectEnumerator().allObjects
self.profilePage = NSMutableArray(array: array)
self.tableView.reloadData()
}
}
}
}
// MARK: - Table view data source
override func objectAtIndexPath(indexPath: NSIndexPath!) -> PFObject? {
var obj : PFObject? = nil
if(indexPath.row < self.profilePage.count){
obj = self.profilePage[indexPath.row] as? PFObject
}
return obj
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return profilePage.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 110
}
else {
return 90
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath?) -> PFTableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PCell", forIndexPath: indexPath!) as! ProfileCell
if let object : PFObject = self.profilePage.objectAtIndex(indexPath!.row) as? PFObject {
cell.WritersName.text = object["writer"] as? String
cell.WritersBlog.text = object["Blog"] as? String
let dateCreated = object.createdAt! as NSDate
let date = NSDateFormatter()
dateFormat.dateFormat = "h:mm a"
cell.timeProfile.text = NSString(format: "%#", date.stringFromDate(dateCreated)) as String
}
return cell
}
// }
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
}

I can see a couple of potential problems with your code.
First, you are adding to the same array every time you perform a query.
If you initialize your array at the time you perform the query, the array will be limited to the current query's results and will not include results from previous fetches.
To do this, add an initialization statement into the section where you are setting up your query.
if let user = PFUser.currentUser() {
profilePage = NSMutableArray() // Reset the profile page array.
query.whereKey("writer", equalTo: PFUser.currentUser()!.username!)
query.addAscendingOrder("createdAt")
...
Additionally, the code in objectsDidLoad: may be overwriting the results that you are creating through your query.
Try disabling the assignment to profilePage in there if you are still not getting the correct results.
override func objectsDidLoad(error: NSError?) {
super.objectsDidLoad(error)
// profilePage = NSMutableArray(array: objects!)
self.tableView.reloadData()
}

Related

Getting data from pointer column in Parse (iOS)

I have seen the following questions.
Get data from a pointer's row in Parse (ios)
and various other questions but still unable to figure out.
I have a class in Parse called 'Plumber'
As you can see the 'practiceArea' is a pointer to this class called 'PracticeArea' (mind the uppercase P in the class)
So from here I want to extract the corresponding 'title' column value for the corresponding pointer. How can I do this?
This is my code so far
//
// Directory.swift
// plumber_main
//
// Created by James on 13/4/16.
// Copyright © 2016 James. All rights reserved.
//
import UIKit
import Parse
class Directory: UITableViewController {
#IBOutlet var plumbersDirectory: UITableView!
var profImages = [PFFile]()
var plumberName = [String]()
var plumberRate = [NSNumber]()
var plumberPracArea = [PFObject]()
var plumberExp = [String]()
var refresher: UIRefreshControl!
func refresh()
{
let query_one = PFQuery(className: "PracticeArea")
query_one.includeKey("title")
let query = PFQuery(className: "plumber")
query.includeKey("practiceArea")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock(
{
(listll: [PFObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(listll!.count) names of the plumbers.")
// Do something with the found objects
if let objects = listll {
for object in objects {
print(object)
self.profImages.append(object["photo"] as! PFFile)
self.plumberName.append(object["name"] as! String)
self.plumberExp.append(object["expLevel"] as! String)
self.plumberPracArea.append(object["practiceArea"] as! PFObject)
print(object ["practiceArea"].objectId)
self.plumberRate.append(object["ratePerHr"] as! NSNumber)
// print(object["plumber_Name"] as! String )
// self.plumbersname.append(object["plumber_Name"] as! String)
//self.lblName.text = object["plumber_Name"] as? String
}
self.plumbersDirectory.reloadData()
}
print(self.plumberName.count)
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
self.tableView.reloadData()
self.refresher.endRefreshing()
})
}
override func viewDidLoad() {
super.viewDidLoad()
refresher = UIRefreshControl()
refresher.attributedTitle = NSAttributedString(string: "Pull to refrehsh")
refresher.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refresher)
refresh()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
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 plumberName.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let plumbercell: plumber_Directory_Cell = tableView.dequeueReusableCellWithIdentifier("plumberlistproto") as! plumber_Directory_Cell
plumbercell.name.text = plumberName[indexPath.row]
plumbercell.exp.text = plumberExp[indexPath.row]
plumbercell.pracArea.text = String(plumberPracArea[indexPath.row])
plumbercell.price.text = String (plumberRate[indexPath.row])
profImages[indexPath.row].getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if imageData != nil {
let image = UIImage(data: imageData!)
plumbercell.mini_image.image = image
}
else
{
print(error)
} }
//cell.textLabel?.text = plumbersname[indexPath.row]
return plumbercell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
print(indexPath.row)
}
}
Try this
func refresh()
{
let query = PFQuery(className: "PracticeArea")
query.includeKey("practiceArea")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock( {
(listll: [PFObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(listll!.count) names of the plumbers.")
// Do something with the found objects
if let objects = listll {
self.plumberName = objects
} else {
self.plumberName.removeAllObjects()
}
self.plumbersDirectory.reloadData()
print(self.plumberName.count)
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
})
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let plumbercell: plumber_Directory_Cell = tableView.dequeueReusableCellWithIdentifier("plumberlistproto") as! plumber_Directory_Cell
let object = plumberName[indexPath.row]
plumbercell.name.text = object["name"]
plumbercell.exp.text = object["expLevel"]
let practiceArea = object["practiceArea"]
plumbercell.pracArea.text = practiceArea["title"]
plumbercell.pracArea.text = String(plumberPracArea[indexPath.row])
plumbercell.price.text = String (plumberRate[indexPath.row])
profImages[indexPath.row].getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if imageData != nil {
let image = UIImage(data: imageData!)
plumbercell.mini_image.image = image
}
else
{
print(error)
} }
//cell.textLabel?.text = plumbersname[indexPath.row]
return plumbercell
}
You were really close and definitely not "doing it all wrong". Since you've already included the key in the query request, when you want the information from that object too, then you just need this
let practiceArea = object["projectArea"] as! PFObject
let title = practiceArea["title"] as? String
you should query the different class if you want to use the pointer with the "includeKey"...
let query: PFQuery = PFQuery(className: "PracticeArea")
query.orderByDescending("createdAt")
query.includeKey("practiceArea")
query.findObjectsInBackgroundWithBlock{
(objects:[PFObject]?, error:NSError?)->Void in
if error == nil{
for object in objects! {
//do stuff with each object
}
}
}

trying to implement the uisearchcontroller but its not giving any search result

import UIKit
class MasterTableViewController: UITableViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
//approches for uisearchbar
var searchNotes: [PFObject] = [PFObject]()
var notesSearchController = UISearchController()
var searchActive: Bool = false
// creating array for holding ojects
var noteObjects: NSMutableArray! = NSMutableArray()
var v = 0
override func viewDidLoad() {
super.viewDidLoad()
self.notesSearchController = UISearchController(searchResultsController: nil)
self.notesSearchController.dimsBackgroundDuringPresentation = true
self.notesSearchController.searchResultsUpdater = self
// Configure the search controller's search bar
self.notesSearchController.searchBar.placeholder = "Search for a user"
self.notesSearchController.searchBar.sizeToFit()
self.notesSearchController.searchBar.delegate = self
self.definesPresentationContext = true
// Set the search controller to the header of the table
self.tableView.tableHeaderView = self.notesSearchController.searchBar
print("check")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if v == 0 {
self.fetchAllObjectsFromLocalDataStore()
//self.fetchAllObjects()
}
}
// fetching data from local datastore and from parse
func fetchAllObjectsFromLocalDataStore(){
let query: PFQuery = PFQuery(className: "Sinhgad")
query.orderByDescending("createdAt")
query.fromLocalDatastore()
query.findObjectsInBackgroundWithBlock { ( objects, error) -> Void in
if (error == nil) {
let temp: NSArray = objects as NSArray!
self.noteObjects = temp.mutableCopy() as! NSMutableArray
self.tableView.reloadData()
}else {
print(error!.userInfo)
}
}
}
func fetchAllObjects(){
let query: PFQuery = PFQuery(className: "Sinhgad")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
PFObject.pinAllInBackground(objects, block: nil )
self.fetchAllObjectsFromLocalDataStore()
// self.tableView.reloadData()
} else {
print(error?.userInfo)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
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
if (self.notesSearchController.active) {
return self.searchNotes.count
} else {
return self.noteObjects.count
}}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MasterTableViewCell
if (self.notesSearchController.active && self.searchNotes.count > indexPath.row) {
// bind data to the search results cell
let object : PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.MasterTitleLabel?.text = object["Title"] as? String
cell.MasterTextLabel.text = object["Fstory"] as? String
cell.MasterTimeLabel.text = object["Time"] as? String
cell.MasterLocationLabel.text = object["Location"] as? String
return cell
} else {
let object : PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.MasterTitleLabel?.text = object["Title"] as? String
cell.MasterTextLabel.text = object["Fstory"] as? String
cell.MasterTimeLabel.text = object["Time"] as? String
cell.MasterLocationLabel.text = object["Location"] as? String
return cell
}}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (self.notesSearchController.active && self.searchNotes.count > 0) {
// Segue or whatever you want
self.performSegueWithIdentifier("openStory", sender: self)
} else {
self.performSegueWithIdentifier("openStory", sender: self)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
if (segue.identifier == "openStory"){
let indexPath = self.tableView.indexPathForSelectedRow!
let object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
upcoming.object = object
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
#IBAction func btnReload(sender: AnyObject) {
fetchAllObjects()
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete ){
let object : PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
// the below for deleting the selected cell's object from server's database
// object.deleteInBackground()
//the below for deleting the selected cell's object from localstorage
object.unpinInBackground()
self.noteObjects.removeObjectAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
// MARK: - Parse Backend methods
func loadSearchUsers(searchString: String) {
let query: PFQuery = PFQuery(className: "Sinhgad")
query.orderByDescending("createdAt")
// Filter by search string
query.whereKey("Notes", containsString: searchString)
self.searchActive = true
query.findObjectsInBackgroundWithBlock {(objects, error) -> Void in
if (error == nil) {
self.searchNotes.removeAll(keepCapacity: false)
self.searchNotes += objects as [PFObject]!
self.tableView.reloadData()
} else {
// Log details of the failure
print("search query error: \(error) \(error!.userInfo)")
}
self.searchActive = false
}
}
// MARK: - Search Bar Delegate Methods
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
// Force search if user pushes button
let searchString: String = searchBar.text!.lowercaseString
if (searchString != "") {
loadSearchUsers(searchString)
}
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
// Clear any search criteria
searchBar.text = ""
// Force reload of table data from normal data source
}
// MARK: - UISearchResultsUpdating Methods
// This function is used along with UISearchResultsUpdating for dynamic search results processing
// Called anytime the search bar text is changed
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchString: String = searchController.searchBar.text!.lowercaseString
if (searchString != "" && !self.searchActive) {
loadSearchUsers(searchString)
}
}
}
The above code is for retrieving stored objects from parse's server and from local storage and show them in table view.
Everything is working fine but I am trying to implement searchbar for adding searching function into my app. The problem is that when am running the app its showing the searchbar but when interacting with search bar its moving to upside and disappearing and when am typing anything.
I am not getting any search result and in NSLog am getting this :
2015-12-03 16:43:48.769 Notes[1015:56944] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x7ff2d48165a0>)
I know am missing something and its not the right way to achieve that function.
If somebody knows how to do it correctly or what am missing than please let me know , thanks and sorry if the way am asking question is not proper !
i just figured out that my 'searchNotes' var of Pfobject have nothing i mean its empty ! for that i tried
cell.MasterTitleLabel?.text = searchNotes["Title"] as! String
but its giving error
cannot subscript a value of type '[PFObject]' with an index of type 'string'
i know its because i declared searchNotes as
searchNotes [PFObject] = [PFObject]()
i should do it something like
searchNotes PFObject = PFObject()
but when am doing this its giving so many errors please help if somebody's know how to fix this
Maybe you shouldn't user PFObject directly.
Can you use another class instead of PFObject
private class object {
var mTitle : String!
var mStory : String!
var mTime : String!
var mLocation : String!
}
And use your code here
let obj : object = object()
obj.mTitle = PFObject["title"];
...etc

SWIFT: Parse column is not appending into array

I'd like to append the 'userVotes' column in the following parse table into an array using Swift -
Here is my code -
import UIKit
import Parse
class MusicPlaylistTableViewController: UITableViewController {
var usernames = [String]()
var songs = [String]()
var voters = [String]()
var numVotes = 0
override func viewDidLoad() {
super.viewDidLoad()
tableView.separatorColor = UIColor.grayColor()
let query = PFQuery(className:"PlaylistData")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects! as? [PFObject] {
self.usernames.removeAll()
self.songs.removeAll()
self.voters.removeAll()
for object in objects {
let username = object["username"] as? String
self.usernames.append(username!)
let track = object["song"] as? String
self.songs.append(track!)
let title = object["userVotes"]! as? String
self.voters.append(title!)
print("Array: \(self.voters)")
}
self.tableView.reloadData()
}
} else {
print(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
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 usernames.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellTrack", forIndexPath: indexPath) as! TrackTableViewCell
//cell.username.text = usernames[indexPath.row]
cell.username.text = usernames[indexPath.row]
cell.songTitle.text = songs[indexPath.row]
cell.votes.text = "\(numVotes)"
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
}
I would like the parse array column to append as follows -
[["user1,"user5,"user9"],["user1,"user2,"user3"],["user4,"user5,"user6"],...]
At this point, I'm getting the following runtime error - fatal error: unexpectedly found nil while unwrapping an Optional value
Since each object that is in your "userVotes" is an array and your you've declared
var voters = [String]()
which is not right because you're saying that there will be one element being appended which is not the case.
So, you should declare voters as...
var voters = Array<Array<String>>()
then as you are downloading it,
for object in objects {
let title = object["userVotes"]! as? [String]
self.voters.append(title!)
print("Array: \(self.voters)")
}

Tableview list is empty causes by findObjectInBackgroundWithBlock return nil

These are my code in swift
This is the code of retrieving the current user's friend list object with parse
class UserViewController: UITableViewController {
var userArray: NSMutableArray = []
#IBOutlet weak var friendListTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
retrieveMessages()
}
func retrieveMessages() {
var query = PFUser.query()
if let username = PFUser.currentUser().username {
query.whereKey("username", equalTo: username)
query.findObjectsInBackgroundWithBlock {
(objects, error) -> Void in
for object in objects! {
let usernames:String? = (object as PFObject)["Friends"] as? String
println(usernames) // It prints "nil"
if usernames != nil {
self.userArray.addObject(usernames!)
}
}
dispatch_async(dispatch_get_main_queue()) {
self.friendListTableView.reloadData()
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return userArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Update - replace as with as!
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = userArray[indexPath.row] as? String
return cell
}
and this is the code of saving current user's friend when the current user add them via username with parse
class addUserViewController: UIViewController {
#IBOutlet weak var usernameTextField: UITextField!
#IBAction func addUser(sender: AnyObject) {
var query = PFUser.query()
query.whereKey("username", equalTo: usernameTextField.text)
println("Pass")
query.getFirstObjectInBackgroundWithBlock{ (object:PFObject!, error: NSError!) -> Void in
if error == nil {
let currentUser = PFUser.currentUser()
let friendList = currentUser.relationForKey("Friends")
var addFriend = object
if addFriend != nil {
friendList.addObject(addFriend)
println("added")
}
PFUser.currentUser().saveInBackgroundWithBlock{
(succeeded: Bool!, error: NSError!) in
if error != nil {
println("Error")
}
else {
println("saved")
}
}
}
}
}
I want to retrieve current user's friend list to show it in tableview but the tableview won't update to show current user's friend list, It's empty and there's no user list in tableview at all. I've tried to fix it and check if method get any object.
The problem is when I use println(usernames) ,It prints "nil" which the method doesn't get any object at all. First I use username as NSArray then I changed it into NSMutableArray and it doesn't have append method like NSArray did so I did a research and add the "add object" line of code in it and change a few things. Right now I'm not sure at all what's wrong with my code and I've been stuck at this for a week now, If my code's wrong somehow can you please guide me where? or fix it would be great. Any help is appreciated
here's the screenshot of my User's class table in parse
https://www.dropbox.com/s/6xp48v3yn0l2hje/Screen%20Shot%202015-06-03%20at%202.10.13%20PM.png?dl=0
here's the screenshot of my current user's friend in parse which is saveก with PFRelation method as seen above
https://www.dropbox.com/s/pd8mt8sf35u1m0v/Screen%20Shot%202015-06-03%20at%202.10.55%20PM.png?dl=0
Thanks in advance!!

Swift Converting PFQuery to String Array for TableView

I am trying to query all of the Parse users in my database and then display each individual user in their own cell in a tableview. I have set up my tableview, but I'm stuck on saving the user query to a string array that can be used within the tableview. I have created a loadParseData function that finds the objects in the background and then appends the objects queried to a string array. Unfortunately I am given an error message on the line where I append the data.
Implicit user of 'self' in closure; use 'self.' to make capture semantics explicit' This seems to me that it is suggestion that I use self. instead of usersArray. because this is within a closure, but I'm given another error if I run it that way, *classname* does not have a member named 'append'
Here is my code:
import UIKit
class SearchUsersRegistrationViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var userArray = [String]()
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadParseData(){
var query : PFQuery = PFUser.query()
query.findObjectsInBackgroundWithBlock {
(objects:[AnyObject]!, error:NSError!) -> Void in
if error != nil{
println("\(objects.count) users are listed")
for object in objects {
userArray.append(object.userArray as String)
}
}
}
}
let textCellIdentifier = "Cell"
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return usersArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as SearchUsersRegistrationTableViewCell
let row = indexPath.row
//cell.userImage.image = UIImage(named: usersArray[row])
//cell.usernameLabel?.text = usersArray[row]
return cell
}
}
The problem is that userArray is an NSArray. NSArray is immutable, meaning it can't be changed. Therefore it doesn't have an append function. What you want is an NSMutableArray, which can be changed and has an addObject function.
var userArray:NSMutableArray = []
func loadParseData(){
var query : PFQuery = PFUser.query()
query.findObjectsInBackgroundWithBlock {
(objects:[AnyObject]!, error:NSError!) -> Void in
if error == nil {
if let objects = objects {
for object in objects {
self.userArray.addObject(object)
}
}
self.tableView.reloadData()
} else {
println("There was an error")
}
}
}
Also, because objects are returned as 'AnyObject' you will have to cast them as PFUsers at some point in order to use them as such. Just something to keep in mind
For getting the user's username and displaying it
// Put this in cellForRowAtIndexPath
var user = userArray[indexPath.row] as! PFUser
var username = user.username as! String
cell.usernameLabel.text = username

Resources