I have a UITableVIew in my iPhone application that populates each cell using an array but the question is how do you populate the array with values retrieved from the firebase database:
func retData(){
rootRef.child("users").child("Test").observeEventType(.Value){
(snap: FIRDataSnapshot) in
}
}
var no1 = ["3","6","3","4","5","20","34","34"]
Table Code:
func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell1 = self.h_table.dequeueReusableCellWithIdentifier("cell1",
forIndexPath: indexPath) as! Hole_Cell
cell1.s_label.text = usersArray[indexPath.row]
firebase data Structure:
--Users
--Test: 1
--Test1: 2
--Test2: 3
--Test4: 4
Try this:
var usersArray: [String]?
func retData() {
rootRef.child("users").observeEventType(.Value, withBlock: { snapshot in
usersArray = [String]()
for user in snapshot.allObjects as! [FIRDataSnapshot] {
let userString = user.value as? String
usersArray?.append(userString!)
}
})
}
***Edit Try this:
var usersArray = [String]()
func retData() {
rootRef.child("users").observeEventType(.Value, withBlock: { snapshot in
let usersDict = snapshot.value as! [String:String]
self.usersArray= Array(usersDict.values)
self.tableView.reloadData()
}
})
}
*** Again Edit: Add this within the closure to account for when users has no data.
if let _ = snapshot.value as? NSNull {
return
} else {
let usersDict = snapshot.value as! [String:String]
self.usersArray= Array(usersDict.values)
self.tableView.reloadData()
}
Check my latest Questions, basically the same stuff. Checkout Firebase UI, very useful.
I used a ViewController with a table view and a Prototype Cell in it. Then this worked for me:
import Firebase
import FirebaseDatabaseUI
class LinksViewController: UIViewController, UITableViewDelegate {
var dataSource: FirebaseTableViewDataSource?
var ref = FIRDatabase.database().reference()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = FirebaseTableViewDataSource.init(query: myQuery(),prototypeReuseIdentifier: "<Your-Identifier>", view: self.tableView)
dataSource?.populateCellWithBlock { (cell: UITableViewCell, obj: NSObject) -> Void in
//Populate your Cell here
}
tableView.dataSource = dataSource
tableView.delegate = self
}
}
Note that the myQuery is basically then your first line.
Related
I have a 2 problems with displaying data in a table from Firebase.
Nothing displayed in TableView from Firebase
I I can not add a link(child) to a variable
Print is working. I get access to Firebase, but nothing is added to TableView. Please, look at my code and correct where i'm wrong.
It's my model
class Exercises {
var titleExercise = ""
var descriptionExercise = ""
init (titleExercise: String, descriptionExercise: String) {
self.titleExercise = titleExercise
self.descriptionExercise = descriptionExercise
}
}
It's my ViewController
class ExercisesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//MARK: Properties
var refWorkout: String = ""
var workout: TrainingProgram?
var ref: DatabaseReference!
#IBOutlet weak var tableView: UITableView!
var exercises = [Exercises]()
//MARK: Methods
override func viewDidLoad() {
super.viewDidLoad()
fetchExercises()
tableView.dataSource = self
tableView.delegate = self
refWorkout = workout!.title
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exercises.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ExercisesTableViewCell
let workouts = exercises[indexPath.item]
cell.titleLabel.text = workouts.titleExercise
cell.descriptionLabel.text = workouts.descriptionExercise
return cell
}
func fetchExercises() {
Database.database().reference().child("programs").child("OPEN SPACE").child("exercises").observe(.childAdded) { (snapshot) in
print(snapshot.value)
if let dict = snapshot.value as? [String: AnyObject] {
let newTitle = dict["title"] as! String
let newDescription = dict["description"] as! String
let exerciseTableCell = Exercises(titleExercise: newTitle, descriptionExercise: newDescription)
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
And I have second question. It also addresses this issue.
As you can see, I have refWorkout = workout!.title Here comes the title from previous ViewController , and refWorkout is a child for Firebase. If I will write next code
ref = Database.database().reference().child("programs").child(refWorkout).child("exercises")
ref.observe(.childAdded) { (snapshot) in
print(snapshot.value)
}
Everything will work. Print will work. But if I insert this code to func fetchExercises() - > It will look like
func fetchExercises() {
Database.database().reference().child("programs").child(refWorkout).child("exercises").observe(.childAdded)...
My app crashed.
Please help me with two questions. Thank you!
My Firebase structure
This is a common mistake, you are reloading the table view too soon and you don't assign/append the result to the data source array
The observe API works asynchronously, put the line to reload the table view into the closure
func fetchExercises() {
Database.database().reference().child("programs").child("OPEN SPACE").child("exercises").observe(.childAdded) { (snapshot) in
print(snapshot.value)
if let dict = snapshot.value as? [String: Any] { // most likely all values are value type
let newTitle = dict["title"] as! String
let newDescription = dict["description"] as! String
let exercise = Exercises(titleExercise: newTitle, descriptionExercise: newDescription)
self.exercises.append(exercise)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
Side note:
You class contains 3 bad practices:
Semantically objects used in collection types should be named in singular form.
Don't declare properties with default values if there is an initializer.
There is too much redundant information in the variable names
And in most cases a struct and even constants are sufficient. I'd recommend
struct Exercise {
let title : String
let description : String
}
In a struct you get the initializer for free.
I am building an app that uses the Twitter API to post to a user's Twitter and load those tweets in a TableView. The table loads correctly when the app first launches. However, after composing and posting a Tweet (confirmed that the Tweet is posted and in the array) the table view is still displaying the same tweets prior without the newly created one. I thought it might have something to do with the asynchronous code so I implemented the DispatchQueue in the refreshData() function. The table view is still not loading the most recently added tweet. How can I change the refreshData() function so that the table updates when Tweet is posted successfully?
import UIKit
import OAuthSwift
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var tweetText: UITextField!
var user: User!
var tweets = [Tweet]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.tableView.rowHeight = 200
let consumerSecret = user.consumerSecret
let consumerKey = user.consumerKey
let oAuthToken = user.oAuthToken
let oAuthSecret = user.oAuthSecret
let oauthswift = user.oauthswift
let screen_name = user.screen_name
print("Feed Consumer Secret: \(consumerSecret)")
print("Feed Consumer Key: \(consumerKey)")
print("Feed Auth Token: \(oAuthToken)")
print("Feed Auth Secret: \(oAuthSecret)")
print("Screen Name: \(screen_name)")
loadFeed(oauthswift: oauthswift)
// Do any additional setup after loading the view.
}
#IBAction func postButtonPushed(_ sender: Any) {
let oauthswift = user.oauthswift
let url = "https://api.twitter.com/1.1/statuses/update.json?status="
let tweet_url = tweetText.text
let encoded_tweet = tweet_url?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)
let new_url = url + encoded_tweet!
let _ = oauthswift.client.post(
new_url, parameters: [:],
success: { response in
let dataString = response.string!
let jsonDict = try? response.jsonObject()
let jsonDict2 = jsonDict as! Dictionary<String,Any>
let tweetText2 = jsonDict2["text"]!
let jsonDict4 = jsonDict2["user"] as! Dictionary<String,Any>
let username = jsonDict4["screen_name"]!
let newTweet = Tweet(tweetText: tweetText2 as! String, username: username as! String)
self.tweets.append(newTweet)
print(username)
//print(dataString)
self.loadFeed(oauthswift: oauthswift)
self.tweetText.text = ""
},
failure: { error in
print(error)
}
)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tweet = tweets[indexPath.row]
if let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? PostCell {
cell.configureCell(tweet: tweet)
return cell
} else {
return PostCell()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tweets.count
}
func loadFeed(oauthswift: OAuth1Swift){
print("LOAD FEED")
let _ = oauthswift.client.get(
"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=\(user.screen_name)", parameters: [:],
success: { response in
let jsonDict = try? response.jsonObject()
let jsonDict2 = jsonDict as! Array<Dictionary<String,Any>>
let arrayCount = jsonDict2.count
for index in 0...arrayCount - 1 {
let jsonDict4 = jsonDict2[index]["user"] as! Dictionary<String,Any>
let tweetText = jsonDict2[index]["text"]!
let username = jsonDict4["screen_name"]!
let newTweet = Tweet(tweetText: tweetText as! String, username: username as! String)
self.tweets.append(newTweet)
print(tweetText)
}
self.refreshData()
}, failure: { error in
print(error)
}
)
}
func refreshData() {
DispatchQueue.main.async{
self.tableView.reloadData()
}
}
}
PostCell.swift
import UIKit
class PostCell: UITableViewCell {
#IBOutlet weak var userLabel: UILabel!
#IBOutlet weak var tweetLabel: UILabel!
var tweet: Tweet!
func configureCell(tweet: Tweet) {
self.userLabel.text = "#\(tweet.username)"
self.tweetLabel.text = tweet.tweetText
print(tweet.tweetText)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Since you are sure that Twitter accepted the post and you appended the new Tweet to the data source there is no need for a full reloadData. You can display just the new row in the table.
In FeedViewController, in method postButtonPushed, inside the oauthswift.client.post's success clousure right after this line self.tweets.append(newTweet) add this:
DispatchQueue.main.async {
self.tableView.beginUpdates()
self.tableView.insertRows(at: [IndexPath(item: self.tweets.count-1, section: 0)],
with: .automatic)
self.tableView.endUpdates()
}
Please see screenshot. There is a repliesTableView, replyTextField and replyButtonin ViewController. repliesTableView cell is called ReplyCell. In ReplyCell there is a commentTableView to list all comments for that reply and a textfField, a commentButton to add new comments.
I have problem when add new replies and new comments. I guess I need to make comments array in ReplyCell empty when I click the Reply button. How can I make this happen? I have no idea how to access comments arrayfrom the root ViewController.
Exact problems: fter clicking commentButton, all comments in every cell doubled. After clicking replyButton, comments went to wrong cell.
Code:
import UIKit
import Firebase
class TopicForumVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var topicNameLabel: UILabel!
#IBOutlet weak var replyNumberLabel: UILabel!
#IBOutlet weak var repliesTableView: UITableView!
#IBOutlet weak var replyTextField: UITextField!
var topicName:String?
var firstKey:String?
var secondKey:String?
var replies = [String]()
var replyButtonTapped = false
override func viewDidLoad() {
super.viewDidLoad()
repliesTableView.delegate = self
repliesTableView.dataSource = self
replyTextField.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
topicNameLabel.text = self.topicName
loadReplies()
}
func loadReplies() {
self.replies = []
DataService.ds.Categories_Base.child(self.firstKey!).child("Topics").observe(.value, with:{(snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
if let topicDict = snap.value as? Dictionary<String,AnyObject> {
if let topic = topicDict["text"] as? String {
if topic == self.topicName {
self.secondKey = snap.key
UserDefaults.standard.setValue(snap.key, forKey: Key_SecondKey)
if let replyDict = topicDict["replies"] as? Dictionary<String,AnyObject> {
for eachDict in replyDict {
if let textDict = eachDict.value as? Dictionary<String,AnyObject> {
if let reply = textDict["text"] as? String {
self.replies.append(reply)
self.replyNumberLabel.text = String(self.replies.count)
}
}
}
}
}
}
}
}
self.repliesTableView.reloadData()
}
})
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return replies.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "ReplyCell") as? ReplyCell {
let reply = replies[indexPath.row]
cell.configureReplyCell(reply: reply)
return cell
} else {
return UITableViewCell()
}
}
#IBAction func replyButtonTapped(_ sender: Any) {
replyButtonTapped = true
if let reply = replyTextField.text, reply != "" {
self.replies = []
DataService.ds.Categories_Base.child(self.firstKey!).child("Topics").child(self.secondKey!).child("replies").childByAutoId().child("text").setValue(reply)
self.repliesTableView.reloadData()
let i = replies.count
for n in 0..<i {
let indexPath = IndexPath(row: n, section: 1)
let cell = repliesTableView.cellForRow(at: indexPath) as! ReplyCell
cell.comments = []
cell.repliesToReplyTableView.reloadData()
}
self.replyTextField.text = ""
self.replyButtonTapped = false
}
}
}
import UIKit
import Firebase
class ReplyCell: UITableViewCell,UITableViewDataSource,UITableViewDelegate, UITextFieldDelegate {
#IBOutlet weak var replyTextView: UITextView!
#IBOutlet weak var repliesToReplyTableView: UITableView!
#IBOutlet weak var commentTextField: UITextField!
var reply:String?
var comments = [String]()
var replyKey:String?
override func awakeFromNib() {
super.awakeFromNib()
self.comments = []
repliesToReplyTableView.delegate = self
repliesToReplyTableView.dataSource = self
commentTextField.delegate = self
loadComments()
}
func configureReplyCell(reply:String) {
self.reply = reply
self.replyTextView.text = self.reply
}
func loadComments() {
self.comments = []
if let firstKey = UserDefaults.standard.value(forKey: Key_FirstKey) as? String, let secondKey = UserDefaults.standard.value(forKey: Key_SecondKey) as? String {
DataService.ds.Categories_Base.child(firstKey).child("Topics").child(secondKey).child("replies").observe(.value, with:{(snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
if let replyDict = snap.value as? Dictionary<String,AnyObject> {
if let reply = replyDict["text"] as? String {
if reply == self.reply {
self.replyKey = snap.key
DataService.ds.Categories_Base.child(firstKey).child("Topics").child(secondKey).child("replies").child(snap.key).child("comments").observe(.value, with: { (commentSnapshot) in
if let commentSnapshots = commentSnapshot.children.allObjects as? [FIRDataSnapshot] {
for commentSnap in commentSnapshots {
if let commentDict = commentSnap.value as? Dictionary<String,AnyObject> {
if let comment = commentDict["text"] as? String {
self.comments.append(comment)
}
}
}
}
self.repliesToReplyTableView.reloadData()
})
}
}
}
}
}
})
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let commentCell = tableView.dequeueReusableCell(withIdentifier:"CommentCell")
commentCell?.textLabel?.text = comments[indexPath.row]
return commentCell!
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#IBAction func commentBtnPressed(_ sender: Any) {
if let comment = commentTextField.text, comment != "" {
self.comments = []
if let firstKey = UserDefaults.standard.value(forKey: Key_FirstKey) as? String, let secondKey = UserDefaults.standard.value(forKey: Key_SecondKey) as? String {
DataService.ds.Categories_Base.child(firstKey).child("Topics").child(secondKey).child("replies").child(self.replyKey!).child("comments").childByAutoId().child("text").setValue(comment)
if let myViewController = parentViewController as? TopicForumVC {
// myViewController.repliesTableView.reloadData()
myViewController.replies = []
}
self.repliesToReplyTableView.reloadData()
self.commentTextField.text = ""
self.replyKey = ""
}
}
}
I don't really know the exact circumstances of what you're building but there are two ideas that may offer some guidance.
1) If your table is displaying content from a data source then you will likely have some kind of reference. E.g. when loading the cells (in this case CustomCell) you'll do something like get the index of the cell and get the same index from the data, and put that data in the cells content. If that's the case, all you have to do on the button click is use tableview.cellForRowAtIndexPath with your sender object, and then remove the array from the data source, e.g. tableDataSource[index] = nil and reload the tableView.
2) If you have a stored property on the CustomCell that you've add specifically for storing this array, then you'd cast the sender object to CustomCell and remove the property, as in Kim's answer.
Hope this helps, but without more information it's kind of hard to tell.
let cell = tableview.cellForRowAtIndexPath(...) as? CustomCell
if cell != nil {
let arr = cell.array
}
BTW: I would re-think storing your array in the cell..
I'm trying to get my data from Firebase Database to particular label in Swift. I have two labels in TableView (as Main.storyboard) tagged 1 and 2.
In a ViewController, I have this code:
import UIKit
import Firebase
import FirebaseDatabase
struct confStruct {
let title : String!
let place : String!
}
class EVS_Table_VC: UITableViewController {
var conf = [confStruct]()
override func viewDidLoad() {
super.viewDidLoad()
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("conferences").queryOrderedByKey().observeEventType(.ChildAdded, withBlock: {
snapshot in
self.tableView.reloadData()
})
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return conf.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = conf[indexPath.row].title
let label2 = cell?.viewWithTag(2) as! UILabel
label2.text = conf[indexPath.row].place
return cell!
}
}
But nothing shows up in a Simulator. Does somebody have a proposition how to resolve this? This struct confStruct initializes my variable from
Database? (title, place).
JSON tree:
"conferences": {
"Key": {
"date": "some date"
"deadline": "some deadline"
"place": "some place"
"title": "some title"
}
}
Change your struct to :-
struct confStruct {
let title : String!
let place : String!
init(title_String : String!, place_String : String!){
self.title = title_String
self.place = place_String
}
}
And:-
FIRDatabase.database().reference().child("conferences/Key").observeSingleEvent(of: .value, with: {(snap) in
if let snapDict = snap.value as? [String:AnyObject]{
let titleS = snapDict["title"] as! String
let placeS = snapDict["place"] as! String
let temp = confStruct.init(title_String: titleS, place_String: placeS)
self. conf.append(temp)
self.tableView.reloadData()
}
})
I'm trying to make a Query with a Pointer in Parse. I have two classes "Discover" and "DiscoveryDetails". I want to get the discovery details of an object that's picked from the discovery class.
Discovery Class
DiscoveryDetails Class - with the discoverID as the pointer.
The discovery objects are displayed in a DiscoveryTableView and on selecting one of the items, I want to query the objects of with an ID related to that selection in a DiscoveryDetailsTableView.
The DiscoveryTableView shows the objects as they appear in the class but the DiscoveryDetailsTableView shows all the objects instead of those related to the Cell I selected.
This is my didSelectRowAtIndexPath Code in the DiscoveryTableView:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let mainStoryboard = UIStoryboard(name: "Discovery", bundle: nil)
let discoveryDetailView = mainStoryboard.instantiateViewControllerWithIdentifier("discoveryDetailTVC") as! DiscoveryDetailTableViewController
let object = self.objectAtIndexPath(indexPath)
discoveryDetailView.titleString = object?.objectForKey("workoutName") as! String
discoveryDetailView.describtionString = object?.objectForKey("workoutDetails") as! String
discoveryDetailView.numberOfWorkouts = object?.objectForKey("numberOfWorkouts") as! Int
discoveryDetailView.imageFile1 = object?.objectForKey("image1") as! PFFile
discoveryDetailView.imageFile2 = object?.objectForKey("image2") as! PFFile
discoveryDetailView.imageFile3 = object?.objectForKey("image3") as! PFFile
let row = indexPath.row //we know that sender is an NSIndexPath here.
let selectedObj = objects![row] // some var where you hold your data
discoveryDetailView.varInDDT = selectedObj
self.navigationController?.pushViewController(discoveryDetailView, animated: true)
}
In my DiscoveryDetailsTableView I have this code:
var titleString: String!
var describtionString: String!
var numberOfWorkouts: Int!
var imageFile1: PFFile!
var imageFile2: PFFile!
var imageFile3: PFFile!
var varInDDT : PFObject?
//MARK: Query for Table with the details
override func queryForTable() -> PFQuery {
let discoveryQuery = PFQuery(className: "DiscoveryDetails")
discoveryQuery.cachePolicy = .CacheElseNetwork
discoveryQuery.whereKey("discoveryID", equalTo: PFObject(withoutDataWithClassName: "Discovery", objectId: "\(varInDDT!.objectId!)"))
discoveryQuery.orderByDescending("createdAt")
return discoveryQuery
}
override func viewDidLoad() {
super.viewDidLoad()
//Header Display
let imagesArray = [imageFile1, imageFile2, imageFile3]
let imagePicked = randomIntergerInRange(0, high: imagesArray.count)
titleLabel.text = titleString.uppercaseString
self.subtitleLabel.text = describtionString
self.numberOfWorkoutsLabel.text = "\(numberOfWorkouts!) Workouts"
//Pick a random Image from the Images
imagesArray[imagePicked].getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error == nil
{
if let imageData = imageData
{
let image = UIImage(data:imageData)
self.backgroundImage.image = image
}
}
})
...
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var discoveryDetailItemsCell:DiscoveryDetailTableViewCell! = tableView.dequeueReusableCellWithIdentifier("DiscoveryDetailTableViewCell") as? DiscoveryDetailTableViewCell
...
discoveryDetailItemsCell.titleLabel.text = object?.objectForKey("exerciseName") as? String
discoveryDetailItemsCell.titleLabel.textColor = UIColor.whiteColor()
discoveryDetailItemsCell.durationAndSetsLabel.text = "\((object?.objectForKey("durationOrSets"))!)"
discoveryDetailItemsCell.minAndSetLabel.text = "mins"
...
return discoveryDetailItemsCell
}
There may be similar questions out there but I have not found anything that answers this or I am probably not seeing my mistake clearly.
Thanks for the help in advance. :)
for query with pointer U have to use query like that
let discoveryQuery = PFQuery(className: "DiscoveryDetails")
discoveryQuery.cachePolicy = .CacheElseNetwork
discoveryQuery.whereKey("discoveryID", equalTo: PFObject(withoutDataWithClassName: "Discovery", objectId: "\(varInDDT!.objectId!)"))
discoveryQuery.orderByDescending("createdAt")
return discoveryQuery
for downloading the detail you have to pass at least ID of the object you want to download from the first viewController to the second or you can pass the whole PFObject
DiscoveryTableView
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("showDetail", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "showDetail"){ // define the segue Name
let controller = (segue.destinationViewController as! DiscoveryDetailTableViewController)
let row = sender!.row //we know that sender is an NSIndexPath here.
let selectedObj = discoveryObjects[row] // some var where you hold your data
controller.varInDDT = selectedObj
}
}
and define the var of PFObject in detailVC
DiscoveryDetailTableViewController
var varInDDT : PFObject?