Swift:从 Internet 下载图像并缓存它们无法正常工作。需要建议

Posted

技术标签:

【中文标题】Swift:从 Internet 下载图像并缓存它们无法正常工作。需要建议【英文标题】:Swift: download image from Internet and cache them doesn't work properly. need suggestions 【发布时间】:2016-08-11 06:47:20 【问题描述】:

我是swift的新手,我正在构建一个从互联网下载图像并显示在UICollectionView中的应用程序,我可以成功实现此功能,但是,您似乎超时滚动屏幕,它再次下载了图像再次,这可能会导致用户的大量数据。我发现我可以使用缓存来解决这个问题,但它不起作用,我认为我做的一切都是正确的,但似乎数据没有存储在缓存中。这是代码,任何人都可以帮我解决这个问题吗?谢谢

var imageCache = [String: UIImage]()
class ViewController: UIViewController 
override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



extension ViewController: UICollectionViewDataSource 

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int 
    return 1


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return 5


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell

    Alamofire.request(.GET, "http://localhost:8888/wordpress/wp-json/wp/v2/posts").responseJSON  (response) in
        if let jsonFile = response.result.value 

            var arrayOfPosts = [Posts]()

            for post in jsonFile as! NSArray 

                let postObj = Posts()
                postObj.postThumbnailUrlString = post.valueForKeyPath("featured_image_thumbnail_url") as! String

                arrayOfPosts.append(postObj)
            


            let imageUrlString: String = arrayOfPosts[indexPath.row].postThumbnailUrlString

            let imageUrl: NSURL = NSURL(string: imageUrlString)!







            if let imageFromCache = imageCache[imageUrlString] 

                cell.imageView.image = imageFromCache
                return
            

            let request = NSURLRequest(URL: imageUrl)
            let session = NSURLSession.sharedSession()
            let dataTask = session.dataTaskWithRequest(request)  (data, response, error) in

                let imageToCache = UIImage(data: data!)

                imageCache[imageUrlString] = imageToCache

                dispatch_async(dispatch_get_main_queue(), 



                    cell.imageView.image = imageToCache
                )

            

            dataTask.resume()



        

    


   return cell


我还有一个 Posts 类和一个自定义的 collectionviewcell。这个收藏了我很久,真的希望有人能帮我解决这个问题。谢谢!!

【问题讨论】:

使用SDWebImage库下载图片,也会缓存图片。 如果您已经在使用 Alamofire,最好考虑使用 AlamofireImage。它们与 SDWebImage 非常相似,有一个 UIImageView 扩展,可以进行异步图像检索,它解决了您上面包含的代码中的许多问题。 (例如,它不仅会缓存,还会处理单元格是否被重用于不同的索引路径等。)您可以将上述所有图像检索和缓存代码替换为cell.imageView.af_setImageWithURL 方法。 我之前试过你说的,因为我已经使用了 Alamofire,但我不知道为什么它和上面的代码做同样的工作。我需要创建缓存来存储数据还是 Alamofire 自动创建它?谢谢,我对swift很陌生~~ 其实我试过AlamofireImage、Haneke等类似的库,都可以成功下载图片,但是都一样,每次滚动collectionview,图片都会快速向右切换,我认为这是因为它没有缓存图像。我不知道为什么会这样? 【参考方案1】:

使用AlamofireImage

Swift 2.2 或 2.3

在你的 pod 文件中添加 --> pod 'AlamofireImage', '~> 2.5'。

斯威夫特 3.1

在你的 pod 文件中添加 --> pod 'AlamofireImage', '~> 3.3'。

在你的代码中加入下面这行代码,它会自动缓存图片并下载它。

override func viewDidLoad() 
     super.viewDidLoad()
     //hit your web service here to get all url's
 

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int

   return arrImageURL.count



func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
 
   cell.imgViewPhoto.af_setImageWithURL(arrImageURL[indexPath.row], placeholderImage: UIImage())

【讨论】:

我之前试过这个,但是我没有放placeholderimage,我是否必须指定placeholderimage或“.at_setImageWithURL(NSURL(字符串:“abc.com”))已经存储了缓存?因为它没有工作就我而言。谢谢 cell.imgViewPhoto.af_setImageWithURL (NSURL (string: "abc.com")) 它已经维护缓存,不需要占位符图像..! 但这对我不起作用。每次滚动屏幕时,图像都会快速切换到右侧,这意味着它再次下载。不知道为什么? 不要在 cellForItemAtIndexPath 中访问您的网络服务,请参阅编辑后的答案 我明白了。让我试试这个。非常感谢。【参考方案2】:

Kingfisher 是一个轻量级且纯 Swift 实现的库,用于从 Web 下载和缓存图像。这个项目深受流行的 SDWebImage 的启发。它为您提供了在下一个应用程序中使用纯 Swift 替代方案的机会。 kingfisher

【讨论】:

您知道翠鸟是否可以将图像附加到单元格而无需再次加载?因为如果我在第 30 个单元格并且我滚动回第 1 个单元格,那么它会再次从内存中加载它们,但如果手机旧了,它仍然很烦人

以上是关于Swift:从 Internet 下载图像并缓存它们无法正常工作。需要建议的主要内容,如果未能解决你的问题,请参考以下文章

将图像从 URL 保存到库,重命名并使用 Swift 共享它

从firebase加载图像并缓存swift3

QNetworkAccessManager 从 Internet 崩溃中下载图像预览

Java - 如果 src 有连字符,则无法从 Internet 下载图像

如何将图像从Firebase下载到Swift,然后更快地在UIImageView中显示?

如何从 URL 下载图像并缓存 Android (React-Native)