0

I have some data in firebase that I am trying to organize by timestamp. I have incorporated this code into cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if let seconds = post["pub_time"] as? Double {
            let timeStampDate = NSDate(timeIntervalSince1970: seconds/1000)
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MM/dd/yyyy"
            let formating = timeStampDate as Date


        let timeAgo = timeAgoSinceDate(formating)

            cell.Time.text = timeAgo

            posts.sort(by: { $0.timeStampDate.compare($1.timeStampDate) == .orderedAscending })


            }

But on the posts.sort(by: { $0.timeStampDate.compare($1.timeStampDate) == .orderedAscending }) I keep getting the error expression type bool is ambiguous without more context and I am not sure what I am doing wrong

This is more or less what my view controller looks like

    var posts = NSMutableArray()

    func loadData(){
        Database.database().reference().child("main").child("posts").queryOrdered(byChild: "pub_time").observeSingleEvent(of: .value, with: { snapshot in

                if let postsDictionary = snapshot .value as? [String: AnyObject] {
                    for post in postsDictionary {
                        posts.add(post.value)

                    }
                    self.TableView.reloadData()
                }

         })
    }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Configure the cell...
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cells", for: indexPath) as! FeedTableViewCell

        //Configure the cell
let post = posts[indexPath.row] as! [String: AnyObject]
cell.Title.text = post["title"] as? String
 if let seconds = post["pub_time"] as? Double {
            let timeStampDate = NSDate(timeIntervalSince1970: seconds/1000)
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MM/dd/yyyy"
            let formating = timeStampDate as Date


        let timeAgo = timeAgoSinceDate(formating)

            cell.Time.text = timeAgo



            }

        return cell
    }
juelizabeth
  • 485
  • 1
  • 8
  • 31
  • There's a lot of oddness in your code and question; First, the question has nothing to do with Firebase so that tag should be removed. Second, you are resorting your posts dataSource array for every cell in the tableView which potentially means that as cell at row 4 is displayed, the datasource order could be changed and it could now be row 2. Third, if this is a timestamp, store it as a timestamp: 20180617095100 as an example. it makes sorting a snap. You're also mixing older NS objects with newer Swift objects for no reason. – Jay Jun 17 '18 at 13:59
  • It's also unclear as to what you are trying to do here - are you trying to calculate how long ago the post was posted and then print that time difference (i.e. 1 hour ago, or 3 days ago) in your cell? – Jay Jun 17 '18 at 14:22
  • @jay yes but that is not my issue. I already figured out how to display if the post was made 3 days ago or a week ago. What I am trying to do is organize the table view based on timestamp to display posts that were made recently to older posts. – juelizabeth Jun 17 '18 at 15:31
  • Then either a) load them from Firebase ordered by timestamp or b), load them from Firebase, sort them and *then* update your tableView. Don't sort during display, sort before. – Jay Jun 17 '18 at 17:50
  • One issue here is converting the snapshot to a dictionary. You will loose your ordering that way. Best practice is to iterate over the snapshot.children and populate the posts dataSource array. That will maintain their order. There's loads of examples here on SO on how to do that. – Jay Jun 18 '18 at 16:27
  • I updated my answer with an example Firebase structure and complete code to load in firebase nodes in order and also how to maintain that order by iterating over the child nodes. – Jay Jun 18 '18 at 17:08

1 Answers1

1

Here's how you sort an array of objects in place; acending is the default order.

Assuming you have a PostClass like this

class PostClass {
   var timeStampDate = "" //assume the timestamps are yyyyMMddhhmmss strings
   var post = ""
}

and they are stored in a posts array

var posts = [PostClass]()

the code to sort the posts object within the array is:

posts.sort(by: {$0.timeStampDate < $1.timeStampDate })

that being said, you may want to consider letting Firebase do the heavy lifting and ordering the data for you so it's presented in the snapshot in the correct order.

Suppose you have a Firebase structure

posts
   post_0
     post: "A post about some stuff"
     timestamp: "2"
   post_1
     post: "Posting about how to post"
     timestamp: "3"
   post_2
     post: "The post for you"
     timestamp: "1"

and we want to load our posts, ordering by the timestamp

let postsRef = self.ref.child("posts")
let postQuery = postsRef.queryOrdered(byChild: "timestamp")
postQuery.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        let dict = snap.value as! [String: Any]
        let post = dict["post"] as! String
        let ts = dict["timestamp"] as! Int
        print(ts, post)
    }
})

and the output

1 The post for you
2 Posting about how to post
3 A post about some stuff

For this example, I used 1, 2, 3 as my timestamp but yyyyMMddhhmmss (20180618101000) format would work as well and provide human readable, proper ordering.

Jay
  • 34,438
  • 18
  • 52
  • 81
  • when I do this, I get an error Argument labels (by:) do not match any available overloads – juelizabeth Jun 17 '18 at 15:33
  • @juelizabeth That message would indicate you are running a older version of Xcode or Swift. This is the current Swift 4 used in Xcode 9.4.1 – Jay Jun 17 '18 at 17:45
  • what is the swift 3 version? – juelizabeth Jun 17 '18 at 19:04
  • I have updated my question to show how I load my table – juelizabeth Jun 17 '18 at 19:07
  • my posts is an NSMutableArray() and when I use the above code to organize my `time posts.sort(by: {$0.timeStampDate < $1.timeStampDate })` it gives me an error that labels (by:) do not match any available overloads – juelizabeth Jun 19 '18 at 00:40
  • @juelizabeth That's a correct error as you should be using Swift (4) classes and arrays instead of the older Obj-C / NS objects. I updated the answer with how to do that - it's really time to start being Swifty! If you must use the NSMutableArray, you would either use compare, descriptors or blocks to do the sorting as the Swift sort function is not really compatible. See [This Answer](https://stackoverflow.com/questions/805547/how-do-i-sort-an-nsmutablearray-with-custom-objects-in-it) for those older, non-swift options. – Jay Jun 19 '18 at 15:24