我正在尝试在我的tableview中加载图像异步,以便能够“离线”读取它们。
当我有连接时,图像会正确显示。否则,当我没有任何联系时它不会因此不起作用。 。 。
这是我正在使用的代码:
import UIKit
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
import SwiftKeychainWrapper
import SwiftyJSON
var posts = [Post]()
var selectedIndexPath: Int = 10
class FeedVC: UIViewController, UITableViewDataSource,
UIImagePickerControllerDelegate, UINavigationControllerDelegate,
UITableViewDelegate {
@IBOutlet weak var feedTableView: UITableView!
private var readPosts: ObserveTask?
override func viewDidLoad() {
super.viewDidLoad()
feedTableView.dataSource = self
feedTableView.delegate = self
readPosts = Post.observeList(from: Post.parentReference.queryOrdered(byChild: "privacy").queryEqual(toValue: false))
{
observedPosts in
posts = observedPosts.reversed()
self.feedTableView.reloadData()
}
}
override var prefersStatusBarHidden: Bool {
return true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.feedTableView.dequeueReusableCell(withIdentifier: "MessageCell")! as UITableViewCell
let imageView = cell.viewWithTag(1) as! CustomImageView
let titleLabel = cell.viewWithTag(2) as! UILabel
let linkLabel = cell.viewWithTag(3) as! UILabel
titleLabel.text = posts[indexPath.row].title
titleLabel.numberOfLines = 0
linkLabel.text = posts[indexPath.row].link
linkLabel.numberOfLines = 0
Storage.getImage(with: posts[indexPath.row].imageUrl){
postPic in
imageView.image = postPic
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard posts[indexPath.row].title != "COMING SOON" else {
return
}
selectedIndexPath = indexPath.row
self.performSegue(withIdentifier: "push", sender: self)
self.feedTableView.reloadData() }
}
let imageCache = NSCache<AnyObject, AnyObject>()
class CustomImageView: UIImageView{
var imageUrlString: String?
func loadImageUsingUrlString(urlString: String){
imageUrlString = urlString
let url = NSURL(string: urlString)
image = nil
if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage{
self.image = imageFromCache
return
}
URLSession.shared
.dataTask(with: url! as URL, completionHandler:
{(data, respones, error) in
if error != nil{
print(error)
return
}
DispatchQueue.main.sync(execute: {
let imageToCache = UIImage(data: data!)
if self.imageUrlString == urlString{
self.image = imageToCache
}
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
self.image = imageToCache
}
)
}).resume()
}
}
我正在使用类Class CustomImageView中的异步函数。
我通常是通过以下方式调用图片:
Storage.getImage(with: posts[indexPath.row].imageUrl){
postPic in
imageView.image = postPic
}
我想问题来自那部分? (我不是sur)
有没有人对我的过程中有什么问题有任何重点?
非常感谢你的帮助!!
- 编辑 -
通过以下方式调用图像存储:
import Foundation
import FirebaseStorage
import UIKit
let STORAGE_BASE = FIRStorage.storage().reference()
class Storage
{
static let REF_POST_IMAGES = STORAGE_BASE.child("post-pics")
static let REF_USER_IMAGES = STORAGE_BASE.child("user-pics")
static let imageCache: NSCache<NSString, UIImage> = NSCache()
static func upload(image: UIImage, to reference: FIRStorageReference, completionHandler: @escaping (String?, Error?) -> ())
{
// Uploads the image
if let imageData = UIImageJPEGRepresentation(image, 0.2)
{
let imageUid = NSUUID().uuidString
let metadata = FIRStorageMetadata()
metadata.contentType = "image/jpeg"
reference.child(imageUid).put(imageData, metadata: metadata)
{
(metadata, error) in
if let error = error
{
completionHandler(nil, error)
}
if let downloadURL = metadata?.downloadURL()?.absoluteString
{
// Caches the image for faster display
imageCache.setObject(image, forKey: downloadURL as NSString)
completionHandler(downloadURL, nil)
}
}
}
else
{
completionHandler(nil, StorageError.compressionFailed)
}
}
// Storage.imageCache.object(forKey: post.imageUrl as NSString)
static func getImage(with url: String, completionHandler: @escaping (UIImage) -> ())
{
if let image = imageCache.object(forKey: url as NSString)
{
completionHandler(image)
}
else
{
let ref = FIRStorage.storage().reference(forURL: url)
ref.data(withMaxSize: 2 * 1024 * 1024)
{
(data, error) in
if let error = error
{
print("STORAGE: Unable to read image from storage \(error)")
}
else if let data = data
{
print("STORAGE: Image read from storage")
if let image = UIImage(data: data)
{
// Caches the image
Storage.imageCache.setObject(image, forKey: url as NSString)
completionHandler(image)
}
}
}
}
}
}
enum StorageError: Error
{
case compressionFailed
}