我正在尝试从 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 等等。
但是,当我开始从存储中下载照片时,我的“标题”信息与我下载的照片不对应:
所以,我只希望每张照片都在收藏 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/