一次只能检索5个用户:Firebase [与Instagram相似] [英] Retrieve only 5 users at a time :Firebase [like Instagram]

查看:122
本文介绍了一次只能检索5个用户:Firebase [与Instagram相似]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天里,我一直在试图为我的应用程序创建一个Instagram类似的Feed。更具体地说:每当用户从底部更新Feed时加载新帖(5)。



我目前使用Firebase存储和显示我的数据。



到目前为止,我的代码如下所示:

  var ref :FIRDatabaseReference! 












$ b $ func viewDidLoad(){
super.viewDidLoad()

tableView.delegate = self
tableView.dataSource = self
$ b $ ref = FIRDatabase.database()。reference()

//在加载视图之后,通常从一个笔尖执行任何其他设置。

$ b $重写func viewDidAppear(animated:Bool){

loadValues()

}

func loadValues(){

dict.removeAll()
posts.removeAll()


ref.child(posts)。queryOrderedByChild timeCreated)。q​​ueryLimitedToLast(5).observeEventType(.ChildAdded){(snapshot:FIRDataSnapshot)in

if timeCreated = snapshot.value![timeCreated] as? Int {
self.dict [timeCreated] = timeCreated
}

如果让postText = snapshot.value![postText] as?字符串{
self.dict [postText] = postText
}


self.posts.append(self.dict)


self.tableView.reloadData()

}




}


func scrollViewDidScroll(scrollView:UIScrollView){

if(scrollView.contentOffset.y + scrollView.frame.size.height)> = scrollView.contentSize.height {

//tableView.tableFooterView.hidden = true
让pagingSpinner = UIActivityIndi​​catorView(activityIndi​​catorStyle:.Gray)
pagingSpinner.startAnimating()
pagingSpinner.hidesWhenStopped = true
pagingSpinner .sizeToFit()
tableView.tableFooterView = pagingSpinner
$ b $ // loadMore(5)

} else {

let pagingSpinner = UIActivityIndi​​catorView (activityIndi​​catorStyle:.Gray)
pagingSpin ner.stopAnimating()
pagingSpinner.hidesWhenStopped = true
pagingSpinner.sizeToFit()
pagingSpinner.hidden = true
tableView.tableFooterView = pagingSpinner
tableView.tableFooterView ?. hidden = true







func tableView(tableView:UITableView,numberOfRowsInSection section :Int) - > Int {

return posts.count

}

func tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath) - > UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(Cell,forIndexPath:indexPath)

如果让postText = posts [indexPath.row] [postText] as? String {
cell.textLabel!.text = postText
}

return cell

}

func loadMore(increment :Int){

//应该在这里进行什么?






所以我在这里要做的是我我正在检测用户何时滚动到底部(在我的scrollViewDidScroll函数中,然后我正在显示活动指示器,并调用函数loadMore(5),其中5是我要显示的新帖子的数量。 >

所以在这里我有两个问题,timeCreated变量只是一个时间戳,我有10个记录(1-10,其中10是最新的,1是最早的)。现在我有了这个代码,tableView显示数据在一个升序视图,从5开始到10结束。

我试图扭转字典数组(后)只需要做一个.reverse(),然后再在loadValues函数中添加字典,因为我只是想在顶部显示10,在底部显示5。



我的第二个问题是我似乎无法找到一个更好的和有效的方式来更新tableView(添加另外5个 记录)。我试图简单地只是有一个默认值为5的全局变量,然后在loadMore上加上五个,然后在字典和帖子上做一个removeAll() - 没有运气(tableView滚动到顶部,我不想)。我也试图玩queryLimitedTolast和queryLimitedToFirst,我最终复制了一些数据。所以换句话说,我还需要检查用户是否可以加载5个新的独特帖子(如果只剩下3个独特的帖子,那么也可以是3个) 。

有没有人有任何想法,我将如何处理这个?

帮助将不胜感激,作为如果您使用的是 tableView

如果您正在使用 tableView

code>更新您的 DataSource ,而不是在特定索引处添加行。使用 struct 是一个常见的问题。



$ p $ struct dataS {

var postData:String!
var index_Initial:Int!
$ b $ init(post:String!,ind:Int!)
{
self.postData = post
self.index_Initial = ind
}




$ ul
  • 声明一个数组类型 dataSourceS

      var dataFeed = dataS]()


  • 将每个帖子的索引保存在 post 节点本身中。可以通过计数 post
    $ $ $ $ $ $ $ $ noOfPosts:100,//假设有在你的DB

    中有100个帖子:{
    Post1:{


    text:asdasdasd,
    index:12

    },

    Post2:{


    text:asdasddasdasd,
    index:13

    }, .....
    }




  • 您的最终代码如下所示: -

     导入UIKit 
    导入Firebase

    类ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {

    var dataFeed = [dataS]()
    让pagingSpinner = UIActivityIndi​​catorView(activityIndi​​catorStyle:.Gray)
    var totalNoOfPost:Int!



    @IBOutlet weak var customTableView:UITableView!



    $ b覆盖func viewDidLoad(){
    super.viewDidLoad()

    customTableView.delegate = self
    customTableView.dataSource = self
    }

    覆盖func viewWillAppear(animated:Bool){
    super.viewWillAppear(animated)

    FIRDatabase.database ().reference()。child(Posts)。observeSingleEventOfType(.Value,withBlock:{(snap)in
    $ b $ if postDict = snap.value as?[String:AnyObject] {

    self.totalNoOfPost = postDict.count

    self.loadMore()
    }
    })

    }

    func numberOfSectionsInTableView(tableView:UITableView) - > Int {
    return 1
    }

    func tableView(tableView:UITableView,numberOfRowsInSection section:Int) - > Int {
    return dataFeed.count
    }

    func tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath) - > UITableViewCell {
    let cell = customTableView.dequeueReusableCellWithIdentifier(customCell)as! customTableViewCell
    if dataFeed.count> 0 {
    cell.poatLabel.text = dataFeed [indexPath.row] .postData
    }
    return cell
    }

    func loadMore(){

    let initialFeedCount:Int = dataFeed.count

    if totalNoOfPost - initialFeedCount - 4> 0(

    FIRDatabase.database()。reference()。child(Posts)。queryOrderedByChild(index)。queryStartingAtValue(totalNoOfPost - initialFeedCount - 4).queryEndingAtValue(totalNoOfPost - initialFeedCount)如果您将recievedSnap.value设置为[[String:AnyObject]),则可以使用observeEventType(.Value,withBlock:{(recievedSnap))作为

    。 b $ b let temp = dataS.init(post:each.1 [text] as!String,ind:each.1 [index] as!Int)
    self.dataFeed.insert(temp, atIndex:5 * Int(self.dataFeed.count / 5))
    self.dataFeed.sortInPlace({$ 0.index_Initial> $ 1.index_Initial})
    if self.dataFeed.count == initialFeedCount + 5 {
    self.dataFeed.sortInPlace({$ 0.index_Initial> $ 1.index_Initial})
    self.customTableView.reloadData()





    },withCancelBlock:{(err)in

    prin t(err.localizedDescription)


    })

    } else if totalNoOfPost - initialFeedCount - 4 <= 0 {

    $ (0).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value,withBlock:{(recievedSnap))b $ b FIRDatabase.database()在

    如果recievedSnap.exists(){

    在recievedSnap.value中为每个! [String:AnyObject] {

    let temp = dataS.init(post:each.1 [text] as!String,ind:each.1 [index] as!Int)

    self.dataFeed.insert(temp,atIndex:5 * Int(self.dataFeed.count / 5))
    self.dataFeed.sortInPlace({$ 0.index_Initial> $ 1.index_Initial} )
    if self.dataFeed.count == initialFeedCount + 4 {
    self.dataFeed.sortInPlace({$ 0.index_Initial> $ 1.index_Initial})
    self.customTableView.reloadData()
    self.pagingSpinner.stopAnimating()
    }
    }
    } else {

    self.pagingSpinner.stopAnimating()
    }

    },withCancelBlock:{(err)in
    $ b $ print(err.localizedDescription)


    })
    }
    }

    func tableView(tableView:UITableView,willDisplayCell cell:UITableViewCell,forRowAtI (indexPath.row + 1)== dataFeed.count {
    print(显示最后一行!)


    pagingSpinner.startAnimating()
    pagingSpinner.hidesWhenStopped = true
    pagingSpinner.sizeToFit()
    customTableView.tableFooterView = pagingSpinner
    loadMore()
    }
    }


    }


    结构数据{

    var postData:String!
    var index_Initial:Int!
    $ b $ init(post:String!,ind:Int!)
    {
    self.postData = post
    self.index_Initial = ind
    }

    }


    For the past few days, I have been trying to create an Instagram-like feed for my app. To be more specific: load new posts (5) each time the user updates the feed from the bottom.

    I am currently using Firebase to both store and display my data.

    My code so far, looks like this:

        var ref:FIRDatabaseReference!
    
        var dict = [String:Any]()
        var posts = [[String:Any]]()
    
       override func viewDidLoad() {
            super.viewDidLoad()
    
            tableView.delegate = self
            tableView.dataSource = self
    
            ref = FIRDatabase.database().reference()
    
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func viewDidAppear(animated: Bool) {
    
            loadValues()
    
        }
    
        func loadValues() {
    
            dict.removeAll()
            posts.removeAll()
    
    
            ref.child("posts").queryOrderedByChild("timeCreated").queryLimitedToLast(5).observeEventType(.ChildAdded) { (snapshot:FIRDataSnapshot) in
    
                if let timeCreated = snapshot.value!["timeCreated"] as? Int {
                    self.dict["timeCreated"] = timeCreated
                }
    
                if let postText = snapshot.value!["postText"] as? String {
                    self.dict["postText"] = postText
                }
    
    
                self.posts.append(self.dict)
    
    
                self.tableView.reloadData()
    
            }
    
    
    
    
        }
    
    
        func scrollViewDidScroll(scrollView: UIScrollView) {
    
            if (scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height {
    
                //tableView.tableFooterView!.hidden = true
                let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
                pagingSpinner.startAnimating()
                pagingSpinner.hidesWhenStopped = true
                pagingSpinner.sizeToFit()
                tableView.tableFooterView = pagingSpinner
    
                //loadMore(5)
    
            } else {
    
                let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
                pagingSpinner.stopAnimating()
                pagingSpinner.hidesWhenStopped = true
                pagingSpinner.sizeToFit()
                pagingSpinner.hidden = true
                tableView.tableFooterView = pagingSpinner
                tableView.tableFooterView?.hidden = true
    
    
            }
    
    
        }
    
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
            return posts.count
    
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    
            if let postText = posts[indexPath.row]["postText"] as? String {
                cell.textLabel!.text = postText
            }
    
            return cell
    
        }
    
        func loadMore(increment:Int) {
    
            //What should go in here?
    
        }
    

    So what I am trying to do here - is that I am detecting when the user has scrolled to the bottom (in my scrollViewDidScroll function. Then I am sinply displaying the activity indicator, and calling the function loadMore(5) where 5 is the amount of new posts that I want to display.

    So here I have two problems. The timeCreated variable is simply a timestamp, where I have ten records (1-10, where 10 is the newest, and 1 is the oldest). With this code that I have now, the tableView displays the data in an ascending view, starting at 5 and ending at 10.

    I have tried to reverse the array of dictionaries (post) by simply doing a .reverse() before appending the dict in the loadValues function. as I simply want it to display 10 at the top, and 5 at the bottom.

    The second problem I have is that I can't really seem to find a good and effective way of updating the tableView (adding another 5 records). I have tried to simply just have a global variable with the default value of 5, and then on loadMore simply plus it by five, and then do a removeAll() on both the dict and posts - with no luck (the tableView scrolls to the top, which I don't want to). I have also tried to play with both queryLimitedTolast and queryLimitedToFirst where I ended up duplicating some data.

    So in other words, I also need to check that the user can in fact load 5 new unique posts (or ex. 3, if there's only 3 unique posts left).

    Does anyone have any ideas on how I would approach this?

    Help would be greatly appreciated, as I have struggled with this for the past two days now.

    解决方案

    If you are using tableView update your DataSource instead of adding a row at a particular index. using struct is a common aproach.

    struct dataS {
    
    var postData : String!
    var index_Initial : Int!
    
    init(post : String!, ind : Int!)
    {
     self.postData = post
     self.index_Initial = ind
      }
    
    }
    

    • Declare an array of type dataSourceS

           var dataFeed= [dataS]()
      

    • For knowing that how many posts you have already retrived , you need to keep the index of each post in the the post node itself.Which can be done by counting the no of children in the post node and incrementing it by one.Or creating a complete separate node of

      noOfPosts: 100, //Lets say there are 100 posts in your DB 
      
       Posts : {
        Post1:{
      
      
           text : asdasdasd,
           index : 12               
      
            },
      
         Post2:{
      
      
           text : asdasddasdasd,
           index : 13              
      
            },.....
       }
      

    Your final code will look something like this:-

     import UIKit
    import Firebase
    
    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var dataFeed = [dataS]()
    let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
    var totalNoOfPost : Int!
    
    
    
    @IBOutlet weak var customTableView: UITableView!
    
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        customTableView.delegate = self
        customTableView.dataSource = self
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        FIRDatabase.database().reference().child("Posts").observeSingleEventOfType(.Value, withBlock: {(snap) in
    
            if let postDict = snap.value as? [String:AnyObject]{
    
                 self.totalNoOfPost = postDict.count
    
                    self.loadMore()
            }
        })
    
    }
    
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataFeed.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = customTableView.dequeueReusableCellWithIdentifier("customCell") as! customTableViewCell
        if dataFeed.count > 0{
        cell.poatLabel.text = dataFeed[indexPath.row].postData
        }
        return cell
    }
    
    func loadMore(){
    
        let initialFeedCount : Int = dataFeed.count
    
        if totalNoOfPost - initialFeedCount - 4 > 0{
    
        FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(totalNoOfPost - initialFeedCount - 4).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in
    
            if recievedSnap.exists(){
    
            for each in recievedSnap.value as! [String:AnyObject]{
                let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int)
                self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5))
                self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
                   if self.dataFeed.count == initialFeedCount+5{
                    self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
                    self.customTableView.reloadData()
    
                }
              }
    
             }
            }, withCancelBlock: {(err) in
    
                print(err.localizedDescription)
    
    
          })
    
        }else if totalNoOfPost - initialFeedCount - 4 <= 0{
    
    
            FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(0).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in
    
                if recievedSnap.exists(){
    
                for each in recievedSnap.value as! [String:AnyObject]{
    
                    let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int)
    
                    self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5))
                    self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
                    if self.dataFeed.count == initialFeedCount+4{
                       self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
                        self.customTableView.reloadData()
                            self.pagingSpinner.stopAnimating()
                    }
                  }
                }else{
    
                self.pagingSpinner.stopAnimating()
                }
    
                }, withCancelBlock: {(err) in
    
                    print(err.localizedDescription)
    
    
            })
        }
    }
    
    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        if (indexPath.row + 1) == dataFeed.count {
            print("Displayed the last row!")
    
    
                        pagingSpinner.startAnimating()
                        pagingSpinner.hidesWhenStopped = true
                        pagingSpinner.sizeToFit()
                        customTableView.tableFooterView = pagingSpinner
                        loadMore()
        }
    }
    
    
    }
    
    
    struct dataS {
    
    var postData : String!
    var index_Initial : Int!
    
    init(post : String!, ind : Int!)
    {
     self.postData = post
     self.index_Initial = ind
      }
    
    }
    

    这篇关于一次只能检索5个用户:Firebase [与Instagram相似]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆