swift - (Swift) 如何对从Firebase Storage 下载的数据进行排序?

标签 swift swift3

我正在尝试从 Firebase(数据库 + 存储)下载一些信息,然后填充一个 Collection View 。但是我无法对从存储下载的数据进行排序!

我的数据库结构如下:

{
  "Cards": {
    "id_0": {
      "title": "0",
      "timestamp": "-0000105",
      "photoURL": "http:// ..."
    },
    "id_1": {
      "title": "1",
      "timestamp": "-0000102",
      "photoURL": "http:// ..."
    },
    "id_2": {
      "title": "2",
      "timestamp": "-0000100",
      "photoURL": "http:// ..."
    },

   (...) // Up to 15
  }
}

首先,我开始从 Firebase 数据库下载信息。然后,我获取其中每一项的“photoURL”数据,并继续从 Firebase 存储下载其对应的照片。

为了获得按日期排序的数据,我使用了按“时间戳”排序的 queryOrdered。它工作正常:它接收 id_0,然后是 id_1,然后是 id_2 等等。

但是,当我开始从存储中下载照片时,我的“标题”信息与我下载的照片不对应:

Example - How it is

Example - How I want it to be

所以,我只希望每张照片都在收藏 View 中的正确位置弹出。

有谁知道最好的方法吗?谢谢!

这是我的代码:

注意:我不喜欢这种使用辅助变量“countCalls”和“secondaryCountCalls”的方法。

import Foundation
import UIKit
import Firebase
import FirebaseStorage
import FirebaseDatabase
import FirebaseAuth

var currentCollectionViewData = [UIImage]()

struct item {
    let photoURL : String!
    let title : String!
    let timestamp : Int!
}

var incomingCards = [item]()

class HomeView: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {

    super.viewDidLoad()

    // Authorization
    let uid = FIRAuth.auth()?.currentUser?.uid

    // Creating reference to database:
    let databaseRef = FIRDatabase.database().reference()

    // Getting current date:
    let currentDate = getCurrentDate()

    var countCalls = -1
    var secondaryCountCalls = -1

    databaseRef.child("CARDS").queryOrdered(byChild: "timestamp").observe(.childAdded, with: { snapshot in

        var timestamp = (snapshot.value as? NSDictionary)?["timestamp"] as! Int

        incomingCards.append(item(title: (snapshot.value as? NSDictionary)?[“title”] as! String,
                                   photoURL: (snapshot.value as? NSDictionary)?["photoURL"] as! String,
                                   timestamp : timestamp))

        currentCollectionViewData.append(UIImage(named: "default_Photo")!)

        self.collectionView!.reloadData()


        countCalls = countCalls + 1  

        FIRStorage.storage().reference(forURL: incomingCards[countCalls].photoURL).data(withMaxSize: 1 * 1024 * 1024) {(data, error) -> Void in
            if (error != nil) {
                print(error)
            } else {
                secondaryCountCalls = secondaryCountCalls+1

                currentCollectionViewData[secondaryCountCalls] = UIImage(data: data!)!
                self.collectionView!.reloadData()

            }
        } 
    }) 

}

还有我对 CollectionView 的扩展:

extension HomeView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize{
        return CGSize(width: self.collectionView.bounds.width, height: 189)
    }



    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return incomingCards.count  
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell

        cell.imageFromCollectionView?.image = currentCollectionViewData[indexPath.row]

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let width = collectionView.frame.width/3 - 1

        return CGSize(width: width, height: width)

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {

        return 0.5
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {

        return 0.5
    }
}

最佳答案

我得到了解决方案!答案是:cellForItemAt 和缓存!

首先,只需从 viewDidLoad() 中删除以下代码:

countCalls = countCalls + 1  

FIRStorage.storage().reference(forURL: incomingCards[countCalls].photoURL).data(withMaxSize: 1 * 1024 * 1024) {(data, error) -> Void in
if (error != nil) {
    print(error)
} else {
    secondaryCountCalls = secondaryCountCalls+1
    incomingCards[secondaryCountCalls].photo = UIImage(data: data!)!
    currentCollectionViewData[secondaryCountCalls] = UIImage(data: data!)!
    self.collectionView!.reloadData()
    }
}

现在,让我们在文件中创建以下扩展代码:

extension UIImageView {

func loadImageUsingCacheWithUrlString(urlString: String) {

    // check cachae for image first
    if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
        self.image = cachedImage
        return
    }

    // otherwise fire off a new download
    let url = NSURL(string: urlString)

    URLSession.shared.dataTask(with: url! as URL, completionHandler: {(data, response, error) in

        if error != nil {
            print(error)
            return
        }

        DispatchQueue.main.sync {

            if let downloadedImage = UIImage(data: data!) {

                imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                self.image = downloadedImage

            }
        }
    }).resume()   
}

最后,在 cellForItemAt 方法中,插入以下代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell

    cell.imageFromCollectionView?.loadImageUsingCacheWithUrlString(urlString: incomingCards[indexPath.row].photoURL)
    currentCollectionViewData[indexPath.row] = cell.imageFromCollectionView.image

}

来自 YouTube 的“Let's Build That App”(链接如下)

Swift: Firebase 3 - How to Load Images from Firebase Storage and Caching (Ep 6)

关于swift - (Swift) 如何对从Firebase Storage 下载的数据进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43295485/

相关文章:

iOS - Parse.com 导出数据自动化

ios - NSCoding 协议(protocol)一致性的类扩展

json - Swift Siesta 编辑获取的实体

ios - 导航栏透明度

ios - 应用程序在模拟器中挂起

swift - 无法使用 'moveDistance' 类型的参数列表调用 '(distance: (CGVector, fadeInWithDuration: Double))'

Xcode 6 - 防止 swift playground 刷新

ios - 如何在 Swift 中按名称/标识符从相机胶卷中获取图像

swift - 不安全的可变寻址器崩溃

swift - 无法将可数 closedRange<int> 类型的值覆盖到预期的参数类型 Rang <int>