2017-08-11 1 views
0

J'ai besoin d'un peu d'aide avec AlamofireImages. Dans l'application, tapant sur une vue cellule de tableau téléchargera et définir une image en utilisant le construit en extension ImageView, voir ci-dessous:Caching AlamofireImage réponses au disque

func sendImageRequest(imageView: UIImageView, item: CatalogItem, isLargeImage: Bool? = false){ 
    let imageURL = ImageManager.URLBuilder(sku: item.sku, largeImage: isLargeImage) 

    // Clear the image so that recycled images are cleared. 
    imageView.image = nil 

    // Create the request and add the token string to the authorization header 
    var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
    urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 

    // If the token exists AND is VALID (not expired) - Get the image. 
    if ImageManager.checkIfTokenExists() && ImageManager.checkTokenIsValid(){ 
     debugPrint("Valid token already exists. Fetching image... TableViewExtension") 
     imageView.af_setImage(withURLRequest: urlRequest){ response in 
      switch response.result{ 
      case .success(let image): 
       debugPrint(response) 
       debugPrint("SUCCESS") 
       break 
      case .failure(let error): 
       debugPrint("Error: \(error)") 
       debugPrint(response.response) 
       break 
      } 
     } 
    } 
    // Else if the token exists AND is INVALID (expired) - Delete the old token, get a new one, and fetch the image 
    else if ImageManager.checkIfTokenExists() && !ImageManager.checkTokenIsValid(){ 
     debugPrint("Token expired... Getting new token.") 
     ImageManager.deleteToken() 
     let tokenRequest = NetRequest.newTokenRequest(url: "http://\(SettingsManager.KEY_ServerURL).ziizii.io/zz/jwt/new?service=images.ziizii.io") 
     tokenRequest.requestJWTToken(){ 
      debugPrint("Token renewed. Fetching image...") 
      imageView.af_setImage(withURLRequest: urlRequest) 
     } 
    } 
    // If the token doesn't exist, request a new one and fetch the image. 
    else{ 
     debugPrint("Requesting new token...") 
     let tokenRequest = NetRequest.newTokenRequest(url: "http://\(SettingsManager.KEY_ServerURL).ziizii.io/zz/jwt/new?service=images.ziizii.io") 
     tokenRequest.requestJWTToken(){ 
      debugPrint("Token aquired. Fetching image...") 
      imageView.af_setImage(withURLRequest: urlRequest) 
     } 
    } 
} 

Ainsi, cette partie, je suis bien avec. Cela fonctionne, Il met en cache l'objet sur le disque et définit l'image ImageView. Si vous appuyez à nouveau dessus plus tard, il vérifie si l'image est dans le cache et si c'est le cas, applique simplement l'image. Soigné.

Maintenant, une nouvelle exigence pour le projet est de donner à l'utilisateur la possibilité de précharger chaque image et de les mettre en cache. Maintenant, je n'utilise plus l'extension AFI ImageView et utilise plutôt le Downloader. B) Lorsqu'un utilisateur appuie sur une cellule, cette extension ImageView vérifie le même cache pour voir si elle a été préchargée et applique cette image. AFI est assez intelligent pour vérifier le cache pour les données d'image avant d'envoyer la demande, donc je suis sûr que c'est possible.

Ce que j'ai à ce jour pour télécharger les images est ci-dessous:

static var downloader = ImageDownloader.default 

static func downloadImage(urlRequest: URLRequestConvertible) 
{ 
    self.downloader.download(urlRequest) { response in 
     switch response.result{ 
     case .success(let image): // If successful, cache the image. 
      print("SUCCESS") 
      break 
     case .failure(let error): // If unsuccessful, remove the cached 404 response and apply a nil image. 
      print("ERROR: \(response.error)") 
      break 
     } 
    } 
} 

Si quelqu'un a une idée pour y parvenir ou des conseils utiles ou astuces, ce serait génial! Merci!

Répondre

0

Eh bien, je suppose que vous téléchargez l'image à partir d'une chaîne en tant qu'URL de téléchargement. J'ai traité le même problème; dans mon cas, je n'utilisais pas Alamofire, j'utilisais une extension à la vue de l'image:

let imageCache = NSCache<AnyObject, AnyObject>() 

l'extension UIImageView {

func downloadImage(from imgURL: String!) { 

    self.image = nil 

    // Check if there's an image in the cache 

    if let cachedImage = imageCache.object(forKey: imgURL as AnyObject) as? UIImage { 
     self.image = cachedImage 
     return 
    } 

    // Otherwise, download image from Firebase via URL-string 

    let url = URLRequest(url: URL(string: imgURL)!) 

    let task = URLSession.shared.dataTask(with: url) { 
     (data, response, error) in 

     if error != nil { 
      print(error!) 
      return 
     } 

     DispatchQueue.main.async { 
      if let image = UIImage(data: data!) { 
       imageCache.setObject(image, forKey: imgURL as AnyObject) 
      } 
      self.image = UIImage(data: data!) 
     } 

    } 

    task.resume() 
} 

}

Maintenant, je résolu le problème de la précontrainte par appeler simplement

for i in objects { // whatever object you're having 

    imageView.downloadImage(fromURL: i.url) 

} 

... dans viewDidLoad().

Maintenant, il parcourt tous les objets personnalisés en téléchargeant et en mettant en cache toutes les images, et si l'utilisateur appuie sur une image, il est instantanément chargé à partir du cache. J'espère que cela vous aide avec votre problème.