使用来自多个Firestore CollectionReference的Array元素填充和排序UITableView

时间:2020-07-15 15:59:59

标签: arrays swift google-cloud-firestore

问题:数组中的大多数帖子都按日期降序加载到UITableView中,但后续集合中的一两个帖子却插入了错误的位置。如何确保所有帖子均按日期在UITableView中的适当位置加载?

我正在根据用户的选择从多个Firestore CollectionReference中加载帖子。由于帖子具有其他属性,因此我按日期降序加载它们,并监听更改。添加了CollectionReference中的元素后,该函数将调用下一个函数,该函数与原始函数非常相似,不同之处在于Collection的路径。

var listener: ListenerRegistration!

func loadPosts() {
    let postsCollection = Firestore.firestore().collection("collection1")
    let postsQuery = postsCollection.order(by: "dateCreated", descending: true)

    listener = postsQuery.addSnapshotListener { (snapshot, error) in
    
    guard let snapshot = snapshot else {
        print("Error retrieving posts: \(error.debugDescription)")
        return
    }
    
        snapshot.documentChanges.forEach({ (change) in
            let data = change.document.data()
            let post = Post.init(data: data)
        
            switch change.type {
            case .added:
                self.onDocumentAdded(change: change, post: post)
            case .modified:
                self.onDocumentModified(change: change, post: post)
            case .removed:
                self.onDocumentRemoved(change: change)
            }
        })
     }

    loadNextCollection()
}

帖子将插入到onDocumentAdded函数的表中。由于帖子可能来自多个来源,因此该函数会验证传入的文档ID尚未包含在posts数组中。

然后,我处理将帖子插入表中适当索引的逻辑。

  1. 获取新索引

  2. 使用新索引将帖子插入数组

  3. 按日期对帖子数组进行排序

  4. 根据文档ID及其在数组中的位置获取帖子位置的新索引

  5. 使用新索引将帖子插入UITableView。

     func onDocumentAdded(change: DocumentChange, post: Post) {
         // If posts array does not contain a post with the same id (prevents adding duplicates)
         if !self.posts.contains(where: { $0.documentId == post.documentId }) {
    
             // get the new index
             let newIndex = Int(change.newIndex)
    
             // insert post into array
             posts.insert(post, at: newIndex)
    
             // sort posts array by date
             posts = posts.sorted() { $0.dateCreated > $1.dateCreated }
    
             // get post's index in the sorted array
             guard let index = self.posts.firstIndex(where: { $0.documentId == post.documentId }) else { return }
    
             // insert post in table view
             self.tableView.beginUpdates()
             self.tableView.insertRows(at: [IndexPath(row: index, section: TableSections.posts)], with: .right)
             self.tableView.endUpdates()
    
         }
     }
    

0 个答案:

没有答案