Note code in Swift - ios

I have seen a similar request but did not respond to my problem.
I am building a simple app notes but when I make the login, the data saved on Parse appear for a few seconds on the TableView and then disappear. What am I doing wrong?
thank you all
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)
self.loginSetup()
}
// Parse - Login
func logInViewController(logInController: PFLogInViewController, shouldBeginLogInWithUsername username: String, password: String) -> Bool {
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: NSError?)
{
println("Faild to log in..")
}
// Parse - sign up
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("Faild to sign up")
}
func signUpViewControllerDidCancelSignUp(signUpController: PFSignUpViewController) {
println("User dismissed sign up")
}
// Parse - logout
#IBAction func logoutAction(sender: AnyObject) {
PFUser.logOut()
self.loginSetup()
}
func loginSetup() {
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
//println(self.noteObjects)
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)
}
}
}
*/
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 as! [NSArray]
var temp: NSArray = objects! as NSArray
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: - 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 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)
}
}
/*
// 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
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} 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
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
}

Related

Getting an Array From Parse into a Table View (Swift 2)

I am trying to pull an array of strings in the from "my_classes" in the "User" class in Parse. I want each individual string within the array to become a separate cell in a tableview when I tap on the search button. This is my array in "my_classes" : ["Physics","Economics","Pre Calculus"]. I want "Physics" as it's own cell, "Economics" as its own cell, etc.
import UIKit
import Parse
class CardSetClassTableViewController: UITableViewController, UISearchBarDelegate {
// MARK: Outlets
#IBOutlet var searchBar: UISearchBar!
#IBOutlet var resultsTableView: UITableView!
// MARK: Variables
var searchResults = [String]()
// MARK: Actions
#IBAction func newClassBarButtonItemPressed(sender: AnyObject) {
self.performSegueWithIdentifier("newClassSegue", sender: self)
}
// MARK: Functions
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func displayAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle:UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar)
{
if reachabilityStatus == kNOTREACHABLE {
self.displayAlert("No Internet Connection", message: "Please connect to the internet before continuing.")
} else {
searchBar.resignFirstResponder()
print("Search word = \(searchBar.text!)")
let classNameQuery = PFQuery(className:"_User")
classNameQuery.whereKey("my_classes".lowercaseString, equalTo: searchBar.text!.lowercaseString)
let query = PFQuery.orQueryWithSubqueries([classNameQuery])
query.findObjectsInBackgroundWithBlock {
(results: [PFObject]?, error: NSError?) -> Void in
if error != nil {
self.displayAlert("Error", message: error!.localizedDescription)
return
}
if let objects = results {
self.searchResults.removeAll(keepCapacity: false)
for object in objects {
let className = object.valueForKey("my_classes") as! String
self.searchResults.append(className)
}
dispatch_async(dispatch_get_main_queue()) {
self.resultsTableView.reloadData()
self.searchBar.resignFirstResponder()
}
}
}
}
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel!.text = searchResults[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let classIndexPath = tableView.indexPathForSelectedRow!
let selectedCell = tableView.cellForRowAtIndexPath(classIndexPath)! as UITableViewCell
let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
spinningActivity.labelText = "Loading"
if reachabilityStatus == kNOTREACHABLE {
spinningActivity.hide(true)
self.displayAlert("No Internet Connection", message: "Please connect to the internet before continuing.")
} else {
// let className : String = String(selectedCell.textLabel!.text!)
self.performSegueWithIdentifier("addCardSet", sender: self)
}
searchBar.resignFirstResponder()
}
}
Thanks!
Try the following...
Edit
var songsArray = [String]()
func fetchUsers() {
let userQuery: PFQuery = PFUser.query()!
//search users by the sepcified username, returns a users! object
//make an array to put the values from the users! array object into
//then append those from your "middle-man" array into your destination array,
//in this example songArray is destination array and songsFromParse is "middle-man" array
userQuery.whereKey("username", equalTo: (username)!)
userQuery.findObjectsInBackgroundWithBlock({
(users, error) -> Void in
var songsFromParse = users!
if error == nil {
if songsFromParse.count != 0 {
self.songsArray = (songsFromParse[i].valueForKey("CurrentSongURLArray") as! Array)
}
self.tableView.reloadData()
} else {
print(error)
}
})
}
You then take your new array that contains the objects that you retrieved, in this example songsArray and use it to populate your tableView. In cellForRowAtIndexPath ...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell ID")
cell?.textLabel?.text = songsArray[indexPath]
return cell!
}

Table view not populating upon view first loading (Swift2 and parse)

Whenever I run my app, the first time the view containing the tableview loads, the table view does not get populated. But once i switch tabs (i am using a tab bar controller), and then switch back, the table view becomes populated. Does anyone have any ideas on how to fix this?
Here is the code:
import UIKit
import Parse
class NotesViewController: UITableViewController {
var notes = [PFObject]()
var cacheNotes = Bool()
#IBOutlet var showContentTableView: UITableView!
func findNotes() {
if let user = PFUser.currentUser()?.username! {
let network = Reachability.isConnectedToNetwork()
let query = PFQuery(className: "notes")
query.whereKey("username", equalTo: user)
if network == true {
print("connected to network")
} else {
("not connected to network")
query.fromLocalDatastore()
}
query.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
self.notes = objects!
for object in objects! {
if self.cacheNotes == true && network == true {object.pinInBackground()}
}
}
})
}
showContentTableView.reloadData()
}
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()
if NSUserDefaults.standardUserDefaults().objectForKey("cacheNotes") == nil {
NSUserDefaults.standardUserDefaults().setObject(true, forKey: "cacheNotes")
}
}
override func viewDidAppear(animated: Bool) {
cacheNotes = NSUserDefaults.standardUserDefaults().objectForKey("cacheNotes") as! Bool
print(cacheNotes)
findNotes()
showContentTableView.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 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 notes.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel?.text = notes[indexPath.row]["title"] as? String
return cell
}
}
When you retrieve data from Parse using findObjectsInBackgroundWithBlock the network operation happens in the background, while the rest of the function keeps executing. So, the showContentTableView.reloadData() happens immediately, before the data has been returned. You need to reload the table data once the network operation has completed, that is, inside the block/closure
func findNotes() {
if let user = PFUser.currentUser()?.username! {
let network = Reachability.isConnectedToNetwork()
let query = PFQuery(className: "notes")
query.whereKey("username", equalTo: user)
if network == true {
print("connected to network")
} else {
("not connected to network")
query.fromLocalDatastore()
}
query.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
self.notes = objects!
showContentTableView.reloadData()
for object in objects! {
if self.cacheNotes == true && network == true {object.pinInBackground()}
}
}
})
}
}
Also, I would suggest that you call findNotes from viewWillAppear rather than viewDidAppear - it will get a head start on populating the data before the table is onscreen.

How to retrieve data from parse server?

Im trying to make a chat app so i almost finish my woking. But i don't know how to get my data from parse to my code back. I tried once but it isn't working there is an error coming when type "query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in" that i want to know how i'm gonna fix this issue.
#IBOutlet var chatTextField: UITextField!
#IBOutlet var DockHight: NSLayoutConstraint!
#IBOutlet var SendButton: UIButton!
#IBOutlet var messageTableview: UITableView!
var messagesArray:[String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.messageTableview.delegate = self
self.messageTableview.dataSource = self
self.chatTextField.delegate = self
let tappGesture:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tableViewTapped")
self.messageTableview.addGestureRecognizer(tappGesture)
//retrive
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func SendButton(sender: UIButton) {
//send button is stoped
//end edding methode for the text
self.chatTextField.endEditing(true)
self.chatTextField.enabled = false
self.SendButton.enabled = false
//create a PFobject
var message = PFObject(className:"Message")
message["Text"] = "\(chatTextField.text)"
message.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success == true) {
NSLog("The Message has been sent")
} else {
NSLog(error!.description)
}
self.SendButton.enabled = true
self.chatTextField.enabled = true
}
}
func retrieveMessage() {
var query:PFQuery = PFQuery(className: "Message")
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
}
}
func tableViewTapped(){
self.chatTextField.endEditing(true)
}
//textfield deligate methode
func textFieldDidBeginEditing(textField: UITextField) {
self.view.layoutIfNeeded()
UIView.animateWithDuration(0.2, animations: {
self.DockHight.constant = 350
self.view.layoutIfNeeded()
}, completion: nil)
}
func textFieldDidEndEditing(textField: UITextField) {
self.view.layoutIfNeeded()
UIView.animateWithDuration(0.3, animations: {
self.DockHight.constant = 44
self.view.layoutIfNeeded()
}, completion: nil)
}
//makrk tableview delegate methode
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.messageTableview.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = self.messagesArray[indexPath.row]
return cell
}
var window: UIWindow?
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messagesArray.count
}
}
Parse documentation is showing this way to get data:
query.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
// Do something with the found objects
if let objects = objects {
for object in objects {
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
The problem is that you are using objects: [AnyObject]! instead of objects: [PFObject]?
Edit:
also you can write like this (objects, error) -> Void in
You need to use [PFObject]? instead of [AnyObject]!
Updated for Swift 3
How to retrieve data from parse?
If you want to use findObjectsInBackgroundWithBlock
For example you can write this:
query.findObjectsInBackground { (objects, error) in
if let objects = objects {
for object in objects {
print(object.objectId)
}
} else {
NSLog("Error: \(error!)")
}
}

Filter result from parse query

Hi Im developing a chat app with parse and I have one group-chat tab. What I would like to accomplish Is that when the user registers he/she can choose from a list of "tags" for example, "cats", "dogs" and "cars". Then when the user is signed in the groups tab only shows group-chats associated to the chosen tags. Right now i have a function where the user can create a group-chat but If possible i want to remove that and use my idea that I explained above.
Here's my code for the group's tab:
import UIKit
// Parse loaded from SwiftParseChat-Bridging-Header.h
class GroupsViewController: UITableViewController, UIAlertViewDelegate {
var groups: [PFObject]! = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if PFUser.currentUser() != nil {
self.loadGroups()
}
else {
Utilities.loginUser(self)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadGroups() {
var query = PFQuery(className: PF_GROUPS_CLASS_NAME)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) in
if error == nil {
self.groups.removeAll()
self.groups.extend(objects as [PFObject]!)
self.tableView.reloadData()
} else {
ProgressHUD.showError("Network error")
println(error)
}
}
}
#IBAction func newButtonPressed(sender: UIBarButtonItem) {
self.actionNew()
}
func actionNew() {
var alert = UIAlertView(title: "Please enter a name for your group", message: "", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "OK")
alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
alert.show()
}
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
if buttonIndex != alertView.cancelButtonIndex {
var textField = alertView.textFieldAtIndex(0);
if let text = textField!.text {
if countElements(text) > 0 {
var object = PFObject(className: PF_GROUPS_CLASS_NAME)
object[PF_GROUPS_NAME] = text
object.saveInBackgroundWithBlock({ (success: Bool, error: NSError!) -> Void in
if success {
self.loadGroups()
} else {
ProgressHUD.showError("Network error")
println(error)
}
})
}
}
}
}
// MARK: - TableView Data Source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.groups.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
var group = self.groups[indexPath.row]
cell.textLabel?.text = group[PF_GROUPS_NAME] as? String
var query = PFQuery(className: PF_CHAT_CLASS_NAME)
query.whereKey(PF_CHAT_GROUPID, equalTo: group.objectId)
query.orderByDescending(PF_CHAT_CREATEDAT)
query.limit = 1000
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
if let chat = objects.first as? PFObject {
let date = NSDate()
let seconds = date.timeIntervalSinceDate(chat.createdAt)
let elapsed = Utilities.timeElapsed(seconds);
let countString = (objects.count > 1) ? "\(objects.count) meddelanden" : "\(objects.count) meddelande"
cell.detailTextLabel?.text = "\(countString) \(elapsed)"
} else {
cell.detailTextLabel?.text = "0 meddelanden"
}
cell.detailTextLabel?.textColor = UIColor.lightGrayColor()
}
return cell
}
// MARK: - TableView Delegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var group = self.groups[indexPath.row]
let groupId = group.objectId as String
Messages.createMessageItem(PFUser(), groupId: groupId, description: group[PF_GROUPS_NAME] as String)
self.performSegueWithIdentifier("groupChatSegue", sender: groupId)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "groupChatSegue" {
let chatVC = segue.destinationViewController as ChatViewController
chatVC.hidesBottomBarWhenPushed = true
let groupId = sender as String
chatVC.groupId = groupId
}
}
}
It sounds like you want to query a class (the one containing chats) with the constraint that an array column property of that class (the one listing each chat's tags) contains some list of tags related to the current user. PFQuery has a method called whereKey:containsAllObjectsInArray: which does exactly that.
To make it work, you need to be clear about whether the list of tags is an array of pointers to tag objects, or an array of strings that are tag names. Naturally, if tags on chats are stored as pointers to objects, then the second parameter should be an array of PFObject, and if they are strings, then the array parameter must be an array of NSString.
Unrelated to the semantics of the query, but important: Doing an unguarded, asynch query for anything in cellForRowAtIndexPath: will be unproductive. This method is called every time a cell scrolls into view, which happens arbitrarily often, and arbitrarily rapidly. Use another method to fetch the table's datasource, then reload the table once the data arrives.
(I think the post has been given a close vote because it asks a specific question, then presents the reader with a lot of code, much of it unrelated, leaving the reader to find the relevant query, and showing no indication of what's been tried so far. The site will work better for you if you give maximum help to those who might answer an otherwise good question).

Delete row in Parse Data browser. So my TableViewController gets updated with the correct amount of cells minus the deleted cell

import UIKit
class FavouritesTableViewController: UITableViewController {
let factBook = FactBook()
var userQuoteData: NSMutableArray = NSMutableArray()
let colorWheel = ColorWheel()
override func viewDidAppear(animated: Bool) {
var refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: Selector("loadData"), forControlEvents: UIControlEvents.ValueChanged)
self.refreshControl = refreshControl
self.loadData()
//********** For resizbale cells UILABEL **************//
// tableView.estimatedRowHeight = 102 // Replace with your actual estimation
// // Automatic dimensions to tell the table view to use dynamic height
// tableView.rowHeight = UITableViewAutomaticDimension
//********** For resizbale cells UILABEL **************//
// if (PFUser.currentUser() == nil) {
// var loginAlert:UIAlertController = UIAlertController(title: "Sign Up / Login", message: "Please sign up or login", preferredStyle: UIAlertControllerStyle.Alert)
//
// loginAlert.addTextFieldWithConfigurationHandler({
// textfield in
// textfield.placeholder = "Your username"
// })
//
// loginAlert.addTextFieldWithConfigurationHandler({
// textfield in
// textfield.secureTextEntry = true
// textfield.placeholder = "Your password"
// })
//
// loginAlert.addAction(UIAlertAction(title: "Login", style: UIAlertActionStyle.Default, handler: {
// alertAction in
// let textField:NSArray = loginAlert.textFields as NSArray!
// let usernameTextField:UITextField = textField.objectAtIndex(0) as UITextField
// let passwoordTextField:UITextField = textField.objectAtIndex(1) as UITextField
//
// PFUser.logInWithUsernameInBackground(usernameTextField.text, password: passwoordTextField.text, block: { (user:PFUser!, error:NSError!) -> Void in
// if ((user) != nil) {
// println("Login Successful")
// }else {
// println("Login Failed")
// }
// })
// }))
//
// loginAlert.addAction(UIAlertAction(title: "Signup", style: UIAlertActionStyle.Default, handler: {
// alertAction in
// let textField:NSArray = loginAlert.textFields as NSArray!
// let usernameTextField:UITextField = textField.objectAtIndex(0) as UITextField
// let passwoordTextField:UITextField = textField.objectAtIndex(1) as UITextField
//
// var user:PFUser = PFUser()
// user.username = usernameTextField.text
// user.password = passwoordTextField.text
//
// user.signUpInBackgroundWithBlock({ (sucsess: Bool!, error:NSError!) -> Void in
// if error == nil {
// println("Sign Up sucessful")
// } else {
// let error = error.userInfo
// println(error)
// }
// })
//
// }))
//
// self.presentViewController(loginAlert, animated: true, completion: nil)
//
// }
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: Segue to Main View Controller
#IBAction func CancelButton(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
//MARK: logout the user
#IBAction func logoutUser(sender: AnyObject) {
let alertController = UIAlertController(title: "Logout", message: "Are you sure you want to logout?", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
PFUser.logOut()
self.performSegueWithIdentifier("selectedQuoteSegue", sender: nil)
var currentUser = PFUser.currentUser() // this will now be nil
println(currentUser)
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
// MARK: Getting Quotes from Parse.com for a particular user
func loadData() {
userQuoteData.removeAllObjects()
var findUserQuoteData: PFQuery = PFQuery(className: "favouriteQuotes")
findUserQuoteData.whereKey("user", equalTo: PFUser.currentUser())
findUserQuoteData.findObjectsInBackgroundWithBlock{ (objects:[AnyObject]!, error:NSError!) -> Void in
if error == nil{
for object in objects{
let user: PFObject = object as PFObject
self.userQuoteData.addObject(user)
}
let array:NSArray = self.userQuoteData.reverseObjectEnumerator().allObjects
self.userQuoteData = NSMutableArray(array: array)
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userQuoteData.count
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {
let cell:FavouritesTableViewCell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath!) as FavouritesTableViewCell
let favouriteQuotes:PFObject = self.userQuoteData.objectAtIndex(indexPath!.row) as PFObject
cell.favouriteQuoteTextView.text = favouriteQuotes.objectForKey("content") as? String
cell.favouriteQuoteTextView.backgroundColor = colorWheel.randomColor()
//Label Animation
cell.favouriteQuoteTextView.alpha = 0
//Date Formatter
// var dateFormatter:NSDateFormatter = NSDateFormatter()
// dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
// cell.timestampLabel.text = dateFormatter.stringFromDate(sweet.createdAt)
//Find User
// var findSweeter:PFQuery = PFUser.query()
// findSweeter.whereKey("objectId", equalTo: sweet.objectForKey("sweeter").objectId)
//
// findSweeter.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
// if error == nil {
// let user:PFUser = (objects as NSArray).lastObject as PFUser
// cell.usernameLabel.text = user.username
//Animation automation
UIView.animateWithDuration(0.5, animations: { () -> Void in
cell.favouriteQuoteTextView.alpha = 1
})
// }
//
// }
cell.favouriteQuoteTextView.scrollRangeToVisible(NSMakeRange(0, 0))
return cell
}
override func tableView(tableView: UITableView?, didSelectRowAtIndexPath indexPath: NSIndexPath?) {
let cell:FavouritesTableViewCell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath!) as FavouritesTableViewCell
var selectedQuoteFromFavourites: AnyObject = self.userQuoteData.objectAtIndex(indexPath!.row)
var selectedQuote: String = selectedQuoteFromFavourites.objectForKey("content") as String!
println(selectedQuote)
NSUserDefaults.standardUserDefaults().setObject(selectedQuote, forKey: "currentQuote") // we are saving a variable called myName and we are giving it the value of "Bob"
NSUserDefaults.standardUserDefaults().synchronize() // Added synchronize as suggested by LAMMERT WESTERHOFF
println(NSUserDefaults.standardUserDefaults().objectForKey("currentQuote")!) // Here we are accessing the variable.
// factBook.currentQuoteIndexArray()
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "segueHappened") // we are saving a variable called myName and we are giving it the value of "Bob"
NSUserDefaults.standardUserDefaults().synchronize() // Added synchronize as suggested by LAMMERT WESTERHOFF
// println(NSUserDefaults.standardUserDefaults().boolForKey("segueHappened")) // Here we are accessing the variable.
self.performSegueWithIdentifier("selectedQuoteSegue", sender: AnyObject?())
}
//MARK: Swipe to delete
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
//MARK: Deleting Object PFQuery
override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
println("touch")
// var selectedQuoteFromFavourites: AnyObject = self.userQuoteData.objectAtIndex(indexPath!.row)
//
// var selectedQuote: String = selectedQuoteFromFavourites.objectForKey("content") as String!
//
// println(selectedQuote)
//Query objectId from parse and delete!
// self.tableView.reloadData()
}
}
I have this loadData() function that gets all the Quotes that a user has stored to my Parse backend. I think it puts the data received from parse into this NSMutable array "userQuoteData". This is what my tableview uses to populate the cells. I added a swipe to delete function at the bottom of this code. it looks like this:
override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
within this swipe to delete function:
How do I tell parse to delete the corrent row with the content of the current cell that is selected(swiped). so I can then reloadData on that tableview with my amended list of quotes from parse. Do I need to find the objectId? Really lost. Thanks in advance.
You've set self.userQuoteData to contain the full PFObjects so simply delete the object; and you'll need to remove the selected object from the self.userQuoteData array before reloading since it informs your table data.
Also, your Parse table doesn't inform your cellForRowAtIndexPath: directly at all -- the self.userQuoteData array does -- so the Parse table doesn't technically need to be updated in order for your table to reflect the changes. So like I've done in the code below, you can delete your object from Parse in the background even as your table reloads.
override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
var selectedQuoteFromFavourites:PFObject = self.userQuoteData.objectAtIndex(indexPath!.row) as PFObject
selectedQuoteFromFavourites.deleteInBackground()
self.userQuoteData.removeObjectAtIndex(indexPath!.row)
self.tableView.reloadData()
}
}

Resources