【发布时间】:2018-03-10 22:20:36
【问题描述】:
我有一个表格视图,它会根据单元类从 Firebase 下载图像。我注意到在使用该应用程序时,具有相同单元格标识符的单元格将在显示新图像之前显示之前下载的图像。这是我改之前的样子。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableData[indexPath.row]["Image"] != nil {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageNotesData", for: indexPath) as! ImageNotesCell
cell.notes.delegate = self
cell.notes.tag = indexPath.row
cell.notes.text = tableData[indexPath.row]["Notes"] as! String
guard let imageFirebasePath = tableData[indexPath.row]["Image"] else {
return cell }
let pathReference = Storage.storage().reference(withPath: imageFirebasePath as! String)
pathReference.getData(maxSize: 1 * 1614 * 1614) { data, error in
if let error = error {
print(error)
} else {
let image = UIImage(data: data!)
cell.storedImage.image = image
}
}
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "notesData", for: indexPath) as! NotesCell
//let noteString = tableData[indexPath.row]["Notes"] as! String
cell.notes.text = tableData[indexPath.row]["Notes"] as! String
cell.notes.delegate = self
cell.notes.tag = indexPath.row
return cell
}
}
知道这不是一个好的用户体验并且看起来很笨重,我尝试将pathReference.getData 移动到我设置数据的位置,但视图会在我的图像完成下载之前出现。我尝试使用完成处理程序,但我仍然遇到问题。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
getSectionData(userID: userID, city: selectedCity, completion: {(sectionString) in
self.setupTableCellView(userID: userID, city: selectedCity, section: sectionString) { (tableData) in
DispatchQueue.main.async(execute: {
self.cityName?.text = selectedCity
self.changeSections.setTitle(sectionString, for: .normal)
self.currentSectionString = sectionString
self.setupTableData(tableDataHolder: tableData)
})
}
})
}
func setupTableCellView(userID: String, city: String, section: String, completion: @escaping ([[String:Any]]) -> () ) {
let databaseRef = Database.database().reference().child("Users").child(userID).child("Cities").child(city).child(section)
var indexData = [String:Any]()
var indexDataArray = [[String:Any]]()
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
for dataSet in snapshot.children {
let snap = dataSet as! DataSnapshot
//let k = snap.key
let v = snap.value
indexData = [:]
for (key, value) in v as! [String: Any] {
//indexData[key] = value
if key == "Image" {
//let pathReference = Storage.storage().reference(withPath: value as! String)
print("before getImageData call")
self.getImageData(pathRef: value as! String, completion: {(someData) in
print("before assigning indexData[key]")
indexData[key] = someData
print("after assigning indexData[key]")
})
} else {
indexData[key] = value
}
}
indexDataArray.append(indexData)
}
completion(indexDataArray)
})
}
func getImageData(pathRef: String, completion: @escaping(UIImage) -> ()) {
let pathReference = Storage.storage().reference(withPath: pathRef as! String)
pathReference.getData(maxSize: 1 * 1614 * 1614, completion: { (data, error) in
if let error = error {
print(error)
} else {
let image = UIImage(data:data!)
print("called before completion handler w/ image")
completion(image!)
}
})
}
我不知道我是否以正确的方式接近这一点,但我想我是。我也猜想getData 调用是异步的,这就是为什么它总是会在显示表格视图后下载。
【问题讨论】:
-
Firebase API 在等待来自服务器的数据时都是异步的。 medium.com/google-developers/…
-
所以我猜我必须在视图加载之前设置我的数据。
-
非常不幸 - 这完全是完全错误的:/ OCC 很难.. 当您使用 Facebook 时,现代“应用程序”(即设备-云系统)看起来真的很容易。但是,看看 Facebook 有多少 IOS 程序员。
标签: ios swift firebase firebase-storage