AlamofireImage磁盘缓存无法正常工作

8
我想使用AlamofireImage从URL下载图像并将其缓存到设备磁盘空间中。我阅读了几篇关于此问题的文章,并发现AlamofireImage通过ImageDownloader类来支持此功能。最有趣的信息在这个SO答案中提供
因此,我尝试为ImageDownloader设置自定义的NSURLCache,以便直接将图像缓存到磁盘中。我通过将内存容量设置为0来实现这一点。然后,我使用这个自定义的ImageDownloader来下载图片。我指定的磁盘路径的文件夹已经在磁盘上创建了,但不幸的是它一直是空的,图像没有以任何方式被缓存。
**编辑:** 需要注意的是,缓存响应并未保存在缓存目录中的文件夹中,而是保存在该文件夹旁边的一个数据库文件中。
请问有人能告诉我我在这里做错了什么吗?非常感谢您的阅读!
func diskImageDownloader(diskSpaceMB: Int = 100) -> ImageDownloader {

    let diskCapacity = diskSpaceMB * 1024 * 1024
    let diskCache = NSURLCache(memoryCapacity: 0, diskCapacity: diskCapacity, diskPath: "alamofireimage_disk_cache")
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.URLCache = diskCache
    let downloader = ImageDownloader(configuration: configuration)
    UIImageView.af_sharedImageDownloader = downloader

    return downloader
}

func getProfileImage(atURL url: String, onComplete: SRServiceResponse<UIImage> -> Void) {
    guard let imageURL = NSURL(string: url) else
    {
        // TODO: Fail here
        return
    }

    let request = NSURLRequest(URL: imageURL)

    let imageDownloader = self.diskImageDownloader()

    imageDownloader.downloadImage(URLRequest: request) { (response) in
        switch response.result
        {
        case .Success(let image):
            // Do something
        case .Failure(let error):
            // Do something
        }
    }
}
2个回答

5

我这么做不是为了声望,仅仅是为了让你在编译器上节省时间。

Swift 3.0中:

class DiskCache: URLCache {


  private let constSecondsToKeepOnDisk = numDaysToKeep*24*60*60 // numDaysToKeep is your own constant or hard-coded value

  override func storeCachedResponse(_ cachedResponse: CachedURLResponse, for request: URLRequest) {

    var customCachedResponse = cachedResponse
    // Set custom Cache-Control for Image-Response
    let response = cachedResponse.response as! HTTPURLResponse

    if let contentType = response.allHeaderFields["Content-Type"] as? String,
        var newHeaders = response.allHeaderFields as? [String: String], contentType.contains("image") {
        newHeaders["Cache-Control"] = "public, max-age=\(constSecondsToKeepOnDisk)"
        if let url = response.url, let newResponse = HTTPURLResponse(url: url, statusCode: response.statusCode, httpVersion: "HTTP/1.1", headerFields: newHeaders) {
            customCachedResponse = CachedURLResponse(response: newResponse, data: cachedResponse.data, userInfo: cachedResponse.userInfo, storagePolicy: cachedResponse.storagePolicy)
        }
    }
    super.storeCachedResponse(customCachedResponse, for: request)
  }
}

请问我该如何使用这个来将一张图片设置到UIImageView上? - markhorrocks
我无法在评论中发布代码响应。太长了。也许你在这方面有点力不从心?你有其他的程序员在那里可以帮助你吗? - horseshoe7

4
为了达成您的目标,需将您用作磁盘缓存的NSURLCache自定义设置以便为存储的图像设置自己的过期日期。
class DiskCache: NSURLCache {
    private let constSecondsToKeepOnDisk = 30*24*60*60 // 30 days

    override func storeCachedResponse(cachedResponse: NSCachedURLResponse, forRequest request: NSURLRequest) {
        var customCachedResponse = cachedResponse
        // Set custom Cache-Control for Image-Response
        if let response = cachedResponse.response as? NSHTTPURLResponse,
            let contentType = response.allHeaderFields["Content-Type"] as? String,
            var newHeaders = response.allHeaderFields as? [String: String] where contentType.containsString("image") {
            newHeaders["Cache-Control"] = "public, max-age=\(constSecondsToKeepOnDisk)"
            if let url = response.URL, newResponse = NSHTTPURLResponse(URL: url, statusCode: response.statusCode, HTTPVersion: "HTTP/1.1", headerFields: newHeaders) {
                customCachedResponse = NSCachedURLResponse(response: newResponse, data: cachedResponse.data, userInfo: cachedResponse.userInfo, storagePolicy: cachedResponse.storagePolicy)
            }
        }
        super.storeCachedResponse(customCachedResponse, forRequest: request)
    }
}

不需要每次都创建一个新的ImageDownloader,可以重复使用共享实例来调用downloadImage方法:UIImageView.af_sharedImageDownloader.downloadImage(URLRequest: request)


1
感谢您的回答。实际上,我的图像响应缺少max-age头。还要注意的是,缓存响应并不保存在缓存目录中的文件夹中,而是保存在与文件夹相邻的数据库文件中。 - Philipp Otto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接