2016-10-27 18 views
6

Chcę użyć AlamofireImage, aby pobrać obrazy z adresu URL, a następnie umieścić je w pamięci podręcznej na dysku urządzenia. Przeczytałem kilka postów na ten temat i okazało się, że AlamofireImage obsługuje to przy pomocy klasy ImageDownloader. Najciekawsza informacja została podana in this SO answer Pamięć podręczna dysku AlamofireImage nie działa

Tak więc próbowałem ustawić niestandardowy NSURLCache dla ImageDownloader tak, aby buforował obrazy bezpośrednio na dysk. Zrobiłem to, ustawiając pojemność pamięci na 0. Następnie używam tego niestandardowego programu ImageDownloader, aby pobrać obraz. Folder określony dla ścieżki dysku jest tworzony na dysku, ale niestety pozostaje pusty i obraz nie jest w żaden sposób buforowany.

** Edycja: ** Należy zauważyć, że buforowane odpowiedzi nie są zapisywane w folderze w katalogu pamięci podręcznych, ale w pliku bazy danych obok folderu.

Czy ktoś może mi powiedzieć, co robię źle tutaj? Wielkie dzięki za przeczytanie!

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

Odpowiedz

4

aby osiągnąć swój cel uczynić swój NSURLCache którego używasz jako diskCache naprawdę zwyczaju, aby ustawić swoją datę ważności dla przechowywanych zdjęć:

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

Zamiast tworzyć nową ImageDownloader za każdym razem można ponownie wykorzystać współużytkowana instancja do wywołania metody downloadImage: UIImageView.af_sharedImageDownloader.downloadImage(URLRequest: request)

+1

Dzięki za odpowiedź. W rzeczywistości w odpowiedzi na obraz brakowało nagłówka maksymalnego wieku. Należy również zauważyć, że buforowane odpowiedzi nie są zapisywane w folderze w katalogu pamięci podręcznych, ale w pliku bazy danych obok folderu. –

4

Nie robię tego dla rep. Tylko po to, aby zaoszczędzić czas przy kompilatorze.

W 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) 
    } 
} 
+0

Jak mogę tego użyć do ustawienia obrazu na UIImageView? – markhorrocks

+0

umm ... użyj instrukcji dla AlamofireImage ?? : D – horseshoe7

+0

Próbowałem tego, nie rozumiem tego. Przepraszam. – markhorrocks

Powiązane problemy