2016-10-27 5 views
6

AlamofireImage를 사용하여 URL에서 이미지를 다운로드 한 다음 장치 디스크 공간에 캐시하고 싶습니다. 이것에 대한 여러 게시물을 읽고 AlamofireImage가 ImageDownloader 클래스의 도움을 받아이를 지원함을 알았습니다. 가장 흥미로운 정보가 주어진다 in this SO answerAlamofireImage 디스크 캐시가 작동하지 않습니다.

그래서 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 
     } 
    } 
} 

답변

4

은 당신의 목표를 만들 도달하려면 당신은 저장된 이미지를 자신의 만료 날짜를 설정하는 diskCache 정말 정의로 사용할 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

감사합니다. 사실 내 이미지 응답에는 최대 연령 헤더가 누락되었습니다. 또한 캐시 된 응답은 캐시 디렉토리의 폴더에 저장되지 않고 폴더 옆의 데이터베이스 파일에 저장됩니다. –

4

담당자에게이 작업을 수행하지 않습니다. 컴파일러로 시간을 절약 할 수 있습니다. 답변에 대한

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

어떻게 이것을 사용하여 UIImageView에 이미지를 설정합니까? – markhorrocks

+0

음 ... AlamofireImage에 대한 지침을 사용 하시겠습니까 ?? : D – horseshoe7

+0

그래, 그것을 시도, 이해가 안 돼요. 죄송합니다. – markhorrocks

관련 문제