I'm using parse to make a simple notes app. When I save a note the cells appear in a random order in the table view. Can anyone help me figure out how to fix this so the cells are in order from when I saved a note. Thanks!
import UIKit
class MasterTableViewController: UITableViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate {
var noteObjects: NSMutableArray! = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (PFUser.currentUser() == nil) {
}else {
self.fetchAllObjectsFromLocalDatastore()
self.fetchAllObjects()
}
}
func fetchAllObjectsFromLocalDatastore() {
var query: PFQuery = PFQuery(className: "Note")
query.fromLocalDatastore()
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
var temp: NSArray = objects!; NSArray.self
self.noteObjects = temp.mutableCopy() as! NSMutableArray
self.tableView.reloadData()
}else {
}
}
}
func fetchAllObjects() {
PFObject.unpinAllObjectsInBackgroundWithBlock(nil)
var query: PFQuery = PFQuery(className: "Note")
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
PFObject.pinAllInBackground(objects, block: { (success, error) in
if error == nil {
self.fetchAllObjectsFromLocalDatastore()
}
})
}else {
println(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 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 self.noteObjects.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MasterTableViewCell
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.masterTitleLabel?.text = object["title"] as? String
cell.masterTextLabel?.text = object["text"] as? String
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("editNote", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
if (segue.identifier == "editNote") {
let indexPath = self.tableView.indexPathForSelectedRow()!
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
upcoming.object = object
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
}
What you need is to set a sorting for your query.
You can sort it by the UpdatedAt date with the following line of code:
query.ascending("updatedAt");
Related
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
I'm trying to make a note app everything runs correctly but after I save the note but the table view is empty.
All of the notes I have written pops up for a split second and disappears and the notes are showing up in the parse data base.
//
// MasterTableViewController.swift
// Notes
//
// Created by uLife on 6/17/15.
// Copyright (c) 2015 uLife. All rights reserved.
import UIKit
class MasterTableViewController: UITableViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate {
var noteObjects: NSMutableArray! = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (PFUser.currentUser() == nil) {
}else {
self.fetchAllObjectsFromLocalDatastore()
self.fetchAllObjects()
}
}
func fetchAllObjectsFromLocalDatastore() {
var query: PFQuery = PFQuery(className: "Note")
query.fromLocalDatastore()
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
var temp: NSArray = objects!; NSArray.self
self.noteObjects = temp.mutableCopy() as! NSMutableArray
self.tableView.reloadData()
}else {
println(error!.userInfo)
}
}
}
func fetchAllObjects() {
PFObject.unpinAllObjectsInBackgroundWithBlock(nil)
var query: PFQuery = PFQuery(className: "Note")
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
PFObject.pinAllInBackground(objects, block: nil)
self.fetchAllObjectsFromLocalDatastore()
}else {
println(error!.userInfo)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Parse Login
// 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 self.noteObjects.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MasterTableViewCell
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.masterTitleLabel?.text = object["title"] as? String
cell.masterTextLabel?.text = object["text"] as? String
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("editNote", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
if (segue.identifier == "editNote") {
let indexPath = self.tableView.indexPathForSelectedRow()!
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
upcoming.object = object
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
}
I think your problem is here. pinAllInBackground is asynchronous method, so fetchAllObjectsFromLocalDatastore will be executed immediately, and obviously there'll be no objects in Local Data Store at that time.
PFObject.pinAllInBackground(objects, block: nil)
self.fetchAllObjectsFromLocalDatastore()
So what you need to do? Implement PFBooleanResultBlock.
PFObject.pinAllInBackground(objects, block: { (success, error) in
if error == nil {
self.fetchAllObjectsFromLocalDatastore()
}
})
I have a Parse Class named "Restaurantes" (Restaurants in english) and currently i can list all the restaurants in a CustomTableView.
Now my goal is when i choose a restaurant from the list, it shows the "menus" of each restaurant. For this I have to pass the Restaurant ObjectId using prepareForSegue and in the new ViewController have a query to list all the "menus" for that restaurant ObjectId.
How can I get the ObjectId of the restaurant that user clicked? (swift)
My Code:
import UIKit
import Parse
import AVFoundation
class ListaTableViewController: UITableViewController {
var queryArray: [PFObject] = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
var query = PFQuery(className:"Restaurantes")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
println("Successfully retrieved \(objects!.count) Restaurantes.")
if let _objects = objects as? [PFObject] {
self.queryArray = _objects
self.tableView.reloadData()
}
} else {
println("Error: \(error!) \(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 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 queryArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> ListaTableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ListaTableViewCell
//Insert text in tableview
let restaurante = queryArray[indexPath.row] as! PFObject
cell.textCell.text = restaurante.objectForKey("nome") as! String
//Insert images in tableview
if let userPicture = restaurante.objectForKey("imagem1") as? PFFile {
userPicture.getDataInBackgroundWithBlock { (imageData: NSData?, error: NSError?) -> Void in
if (error == nil) {
cell.imageBg.image = UIImage(data:imageData!) }
}
}
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "cell" {
if let destination = segue.destinationViewController as? MenuPageViewController {
if let blogIndex = tableView.indexPathForSelectedRow()?.row {
}
}
}
}
}
it should be something like this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "cell" {
if let destination = segue.destinationViewController as? MenuPageViewController {
if let blogIndex = tableView.indexPathForSelectedRow()?.row {
// Get the object restaurant object from your array
let restaurante = queryArray[blogIndex] as! PFObject
// set object id to the property in destination
destination.resturantId = restaurant.objectId
}
}
}
}
I just started coding and I search several posts, but I can't find why my data in the app is not showing up.
It's fetching my data, but I don't understand how I can add it to the tableView My first code for the "override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell" is still there, and please explain why it didn't work. Want to understand why it wasn't working.
class MasterTableViewController: PFQueryTableViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate {
var noteObjects: NSMutableArray! = NSMutableArray()
#IBAction func logoutAction(sender: UIBarButtonItem) {
PFUser.logOut()
viewDidAppear(true)
}
// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Configure the PFQueryTableView
self.parseClassName = "Note"
self.textKey = "title"
self.pullToRefreshEnabled = true
self.paginationEnabled = false
}
// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
var query = PFQuery(className: "Note")
query.orderByAscending("updatedAt")
return query
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (PFUser.currentUser() == nil) {
var logInViewController = PFLogInViewController()
logInViewController.delegate = self
var signUpViewController = PFSignUpViewController()
signUpViewController.delegate = self
logInViewController.signUpController = signUpViewController
self.presentViewController(logInViewController, animated: true, completion: nil)
}else {
//self.fetchAllObjectsFromLocalDatastore()
//self.fetchAllObjects()
}
}
func fetchAllObjectsFromLocalDatastore() {
var query: PFQuery = PFQuery(className: "Note")
//query.cachePolicy = .CacheElseNetwork
query.fromLocalDatastore()
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if (error == nil) {
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
var temp: PFObject = PFObject()
self.noteObjects = temp.mutableCopy() as! NSMutableArray
self.tableView.reloadData()
}else {
println(error!.userInfo)
}
}
}
func fetchAllObjects() {
PFObject.unpinAllObjectsInBackgroundWithBlock(nil)
var query: PFQuery = PFQuery(className: "Note")
//query.cachePolicy = .CacheElseNetwork
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if (error == nil) {
PFObject.pinAllInBackground(objects, block: nil)
self.fetchAllObjectsFromLocalDatastore()
}else {
println(error!.userInfo)
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return self.noteObjects.count
}
//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell") as! MasterTableViewCell!
if cell == nil {
cell = MasterTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
// Extract values from the PFObject to display in the table cell
if let titleLabel = object?["title"] as? String {
cell?.masterTitleLabel?.text = titleLabel
}
if let textView = object?["text"] as? String {
cell?.masterTextLabel?.text = textView
}
return cell
}
//First try did find the code above afterwards
/*override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MasterTableViewCell
// Configure the cell...
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.masterTitleLabel?.text = object["title"] as? String
cell.masterTextLabel?.text = object["text"] as? String
return cell
}*/
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("editNote", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
if (segue.identifier == "editNote") {
let indexPath = self.tableView.indexPathForSelectedRow()!
var object: PFObject = self.noteObjects.objectAtIndex(indexPath.row)as! PFObject
upcoming.object = object;
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
let objectToDelete = noteObjects?[indexPath.row] as! PFObject
objectToDelete.deleteInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// Force a reload of the table - fetching fresh data from Parse platform
self.fetchAllObjects()
} else {
// There was a problem, check error.description
}
}
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
//Signup and Login ViewController created by Parse
func logInViewController(logInController: PFLogInViewController, shouldBeginLogInWithUsername username: String, password: String) -> Bool {
logInController.fields = (PFLogInFields.UsernameAndPassword
| PFLogInFields.LogInButton
| PFLogInFields.SignUpButton
| PFLogInFields.PasswordForgotten)
if (!username.isEmpty || !password.isEmpty) {
return true
}else {
return false
}
}
func logInViewController(logInController: PFLogInViewController, didLogInUser user: PFUser) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func logInViewController(logInController: PFLogInViewController, didFailToLogInWithError error: NSError?) {
println("Failed to log in...")
}
func signUpViewController(signUpController: PFSignUpViewController, shouldBeginSignUp info: [NSObject : AnyObject]) -> Bool {
if let password = info["password"] as? String {
return count(password.utf16) >= 8
} else {
return false
}
}
func signUpViewController(signUpController: PFSignUpViewController, didSignUpUser user: PFUser) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func signUpViewController(signUpController: PFSignUpViewController, didFailToSignUpWithError error: NSError?) {
println("Failed to sign up...")
}
func signUpViewControllerDidCancelSignUp(signUpController: PFSignUpViewController) {
println("User dissmissed sign up.")
}
}
update: changing the numberOfSections didn't help
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
Solved
It's working now, changed this part of the code
func fetchAllObjectsFromLocalDatastore() {
var query: PFQuery = PFQuery(className: "Note")
//query.cachePolicy = .CacheElseNetwork
query.fromLocalDatastore()
query.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if (error == nil) {
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
//var temp: PFObject = PFObject()
//self.noteObjects = temp.mutableCopy() as! NSMutableArray
//println(self.noteObjects)
self.tableView.reloadData()
}else {
println(error!.userInfo)
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return objects!.count
}
#DenisE I had the same trouble and your solution of adding self.tableView.reloadData() fixed it. The reason we have to do this is I believe because view is already appeared and data was queried after that, so unless we reload that queried data in view it won't reflect in UI.
You need to set your number of sections to 1 otherwise there is no section to show and so no content either.
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
i trie to find parse users via UISearchBar and display results in a table view.
When i heat search, nothing happened...
My idea was to use the searchText.text as a query to PFUser.
Should i try to use searchBar with search display controller instead ?
Any idea ?
import UIKit
class AllFriendsTableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
#IBOutlet var SearchDisplay: UISearchDisplayController!
var userList:NSMutableArray = NSMutableArray()
func searchBarShouldBeginEditing(searchBar: UISearchBar!) -> Bool {
return true
}
func searchBarShouldEndEditing(searchBar: UISearchBar!) -> Bool {
return true
}
func searchBar(searchBar: UISearchBar!, textDidChange searchText: String!) {
loadUser()
}
#IBOutlet var searchText: UISearchBar!
func loadUser () {
userList.removeAllObjects()
var findUser:PFQuery = PFUser.query()
findUser.whereKey("username", equalTo: searchText.text)
findUser.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
if !(error != nil) {
// The find succeeded.
println("succesfull load Users")
// Do something with the found objects
for object in objects {
self.userList.addObject(object)
println("users added to userlist")
}
self.tableView.reloadData()
} else {
// Log details of the failure
println("error loadind user ")
println("error")
}
}
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
if tableView == searchDisplayController.searchResultsTableView {
return userList.count
}
else {
return 0
}
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell: AllFirendsTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)as AllFirendsTableViewCell
let users:PFObject = self.userList.objectAtIndex(indexPath!.row) as PFObject
var findUserName:PFQuery = PFUser.query()
findUserName.whereKey("username", containsString: searchText.text)
findUserName.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!) -> Void in
if !(error != nil) {
if let user:PFUser = users as? PFUser {
cell.userNameTextField.text = user.username
println("user exist")
// define avatar poster
if let avatarImage:PFFile = user["profileImage"] as? PFFile {
avatarImage.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in
if !(error != nil) {
let image:UIImage = UIImage(data: imageData)
cell.avatarImage.image = image as UIImage
cell.avatarImage.layer.cornerRadius = 24
cell.avatarImage.clipsToBounds = true
}
}
}
else {
cell.avatarImage.image = UIImage(named: "Avatar-1")
cell.avatarImage.layer.cornerRadius = 24
cell.avatarImage.clipsToBounds = true
}
}
}
}
return cell
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
navigationController.navigationBar.hidden = false
loadUser()
}
override func viewDidAppear(animated: Bool) {
}
override func viewDidLoad() {
// Do any additional setup after loading the view, typically from a nib.
}
}
I suspect this might be due to you attempting to reload the tableview from the background thread that your network request occurs on. UI updates should happen from the main thread.
In your loadUser() function try doing your tableview reload from the main thread, as follows:
NSOperationQueue.mainQueue().addOperationWithBlock({
self.tableView.reloadData()
})
That may fix your issue.