Кэш диска AlamofireImage не работает

Я хочу использовать AlamofireImage для загрузки изображений с URL-адреса, а затем кэшировать их на диске устройства. Я прочитал несколько сообщений об этом и узнал, что AlamofireImage поддерживает это с помощью ImageDownloader. Самая интересная информация была дана в этом ответе SO

Поэтому я попытался установить собственный NSURLCache для ImageDownloader, чтобы он кэшировал изображения непосредственно на диск. Я сделал это, установив объем памяти равным 0. Затем я использую этот пользовательский ImageDownloader для загрузки изображения. Папка, которую я указал для пути к диску, создается на диске, но, к сожалению, она остается пустой, и изображение никак не кэшируется.

** Редактировать: ** Важно отметить, что кэшированные ответы сохраняются не в папке в каталоге caches, а в файле базы данных рядом с папкой.

Может ли кто-нибудь сказать мне, что я делаю неправильно здесь? Большое спасибо за чтение!

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
        }
    }
}

person Philipp Otto    schedule 27.10.2016    source источник


Ответы (2)


Чтобы достичь своей цели, сделайте свой NSURLCache, который вы используете в качестве diskCache, действительно настраиваемым, чтобы установить собственную дату истечения срока действия для сохраненных изображений:

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)

person FBente    schedule 27.10.2016
comment
Спасибо за Ваш ответ. На самом деле в моем ответе на изображение отсутствовал заголовок максимального возраста. Также важно отметить, что кэшированные ответы сохраняются не в папке в каталоге caches, а в файле базы данных рядом с папкой. - person Philipp Otto; 27.10.2016

Я делаю это не для представителя. Просто чтобы сэкономить ваше время с компилятором.

В 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)
  }
}
person horseshoe7    schedule 16.12.2016
comment
Как я могу использовать это, чтобы установить изображение в UIImageView, пожалуйста? - person markhorrocks; 27.01.2017
comment
Я не могу опубликовать ответ кода в комментариях. Слишком долго. Возможно, вы немного не в своей тарелке в этом вопросе? У вас есть другие кодеры, работающие там, которые могут вам помочь? - person horseshoe7; 30.01.2017