为什么tableview中的数据总是随机排序?

时间:2020-06-18 20:26:49

标签: ios swift firebase google-cloud-firestore firebase-storage

这与代码中的问题部分有关,除了一件事情外,它几乎可以正常工作。数据始终是随机排序的。关于代码:我应该从firebase接收数据(CoffeeShop和.jpg的名称)并在tableView中显示照片

#!/bin/bash
#PBS -N test
#PBS -o std.out
#PBS -j oe
#PBS -l nodes=1:ppn=1
cd $PBS_O_WORKDIR
echo " "
echo "Job started on `hostname` at `date`"
./main.out >> ./main.result
echo "Job ended at `date`"
echo " "

我怎么说:它有效。但是应该在firebase集合中对其进行排序。对不起,我的英语。(

在编辑代码(如按位置排序的注释行中所示)之后。这是打印语句的结果:

var coffeeShopLists: [CoffeeShopList] = []

struct CoffeeShopList {
    let name: String
    let shopImage: UIImage
}

func loadShops () {
        coffeeShopLists = []
        db.collection("coffeeShop").getDocuments { (querySnapshot, error) in
            if let e = error {
                print("Error\(e)")
            } else {
                if let snapshotDocuments = querySnapshot?.documents {
                    for doc in snapshotDocuments {
                        let data = doc.data()
                        print(doc.data())
                        if let shop = data["name"] as? String {
                            print(shop)
                             self.getFoto(named: shop)
//                            self.coffeeShopLists.append(shopList)  //retrieving Data from firebase
                            DispatchQueue.main.async {
                                self.tableView.reloadData()
                            }
                        }
                    }
                }
            }
        }      
    }

func getFoto (named: String) {
        let storage = Storage.storage().reference().child("CoffeeShops/\(named).jpg")
        storage.getData(maxSize: 1 * 1024 * 1024) {data, error in
        if let error = error {
           return print(error)
        } else {
            if let image = UIImage(data: data!) {
                let newList = CoffeeShopList(name: named, shopImage: image)
                self.coffeeShopLists.append(newList)
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }

    }
          
   }        
 }

override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.register(UINib(nibName: "CoffeeShopCell", bundle: nil), forCellReuseIdentifier: "ReusableCell")
        loadShops()
    }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ReusableCell", for: indexPath) as! CoffeeShopCell
        cell.shopImage.image = coffeeShopLists[indexPath.row].shopImage
        return cell
    }

结构每次都以随机顺序感受

因此,即时通讯的方向正确。完成它的最后一个问题:如何按第三个值对结构进行排序

["position": 1, "name": soren]
soren
["position": 2, "name": ramozoti]
ramozoti
["position": 3, "name": coffeesoul]
coffeesoul //until this part the result is always the same(correct) and it should be by this order. But the results bellow is always in random order. That part belong to function getFoto()
coffeesoul
[CoffeeShop.CoffeeShopList(name: "coffeesoul", shopImage: <UIImage:0x600000e17600 anonymous {1080, 1080}>)]
ramozoti
[CoffeeShop.CoffeeShopList(name: "coffeesoul", shopImage: <UIImage:0x600000e17600 anonymous {1080, 1080}>), CoffeeShop.CoffeeShopList(name: "ramozoti", shopImage: <UIImage:0x600000e17840 anonymous {621, 621}>)]
soren
[CoffeeShop.CoffeeShopList(name: "coffeesoul", shopImage: <UIImage:0x600000e17600 anonymous {1080, 1080}>), CoffeeShop.CoffeeShopList(name: "ramozoti", shopImage: <UIImage:0x600000e17840 anonymous {621, 621}>), CoffeeShop.CoffeeShopList(name: "soren", shopImage: <UIImage:0x600000e10000 anonymous {1080, 1080}>)]

就这样,它现在可以工作了。我做了额外的功能

[CoffeeShop.CoffeeShopList(name: "ramozoti", shopImage: Optional(<UIImage:0x600003b27de0 anonymous {621, 621}>), position: 2), CoffeeShop.CoffeeShopList(name: "soren", shopImage: Optional(<UIImage:0x600003b34480 anonymous {1080, 1080}>), position: 1), CoffeeShop.CoffeeShopList(name: "coffeesoul", shopImage: Optional(<UIImage:0x600003b31b00 anonymous {1080, 1080}>), position: 3)]

并将其传递到 func sort () { sortedShopLists = coffeeShopLists.sorted {$0.position < $1.position} } 之后的getFoto()函数中 也许这是解决我问题的一种更优雅的方法,但我发现了这一点。

3 个答案:

答案 0 :(得分:0)

如果您未在查询中指定文档顺序,则Firestore不保证顺序。除非您在查询中指定,否则文档从根本上不排序。因此,如果订购对您来说很重要,那么您就得自己安排。

答案 1 :(得分:0)

我是Swift的学习者,并且遇到了相同的问题,我通过使用.order找出了方法

db.collection(Constants.FStore.collectionName).order(by: Constants.FStore.dateField).addSnapshotListener { (querySnapShot, error) in

在持久化的同时,我也持久化了一个日期字段,并以此进行订购。您可以按其他字段订购。

您的代码可能是

db.collection("coffeeShop").order(by: <<your field>>).getDocuments { (querySnapshot, error)

正如我所说,我是Swift的学习者,但我希望这会有所帮助。

答案 2 :(得分:0)

Firestore控制台通过其密钥对文档进行排序。如果您希望代码中的内容相同,可以

db.collection("coffeeShop")order(by: FieldPath.documentID()).getDocuments(...

另请参阅:Order by document id firestore?


您的更新和评论都指向有关与这些文档相关的照片的加载。

以正确的顺序开始加载照片。但是由于每张照片的加载时间不同,因此可能会以另一顺序完成

如果您希望照片按照文档的显示顺序显示,则应确保从维护文档顺序的列表中进行操作。

例如,您可以在开始加载其照片之前将每个文档添加到coffeeShopLists,然后用该照片更新 coffeeShopLists中的项目。

因此,在您的loadFotos中,您将需要执行以下操作:

for doc in snapshotDocuments {
    let data = doc.data()
    if let shop = data["name"] as? String {
        self.coffeeShopLists.append(shopList)
        self.getFoto(named: shop, self.coffeeShopLists.length - 1)
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

这里的变化是我们将文档的索引传递到getFoto函数中,以便它知道要更新数组中的哪个元素。

然后在getFoto中对数组项进行罚款,并更新,而不是添加新项。