web-dev-qa-db-fra.com

SDWebImage Télécharger l'image et la stocker dans le cache pour la clé

Bonjour, j'utilise le framework SDWebImage dans un projet et je souhaite télécharger et mettre en cache des images, mais je pense que mon code stocke une image dans le cache deux fois? Est-il possible de stocker l'image dans le cache par une clé une seule fois? Voici mon code.

         SDWebImageManager *manager = [SDWebImageManager sharedManager];
         [manager downloadWithURL:[NSURL URLWithString:url] options:0 progress:^(NSUInteger receivedSize, long long expectedSize) {

          } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {

            if(image){
                NSString *localKey = [NSString stringWithFormat:@"Item-%d", i];
                [[SDImageCache sharedImageCache] storeImage:image forKey:localKey];
            }

          }];  

Y a-t-il quelque chose que j'ai raté? On dirait que faire cela dans mon instrument d'allocations consomme beaucoup de mémoire.

21
AgnosticDev

Je suis surpris que personne n'ait répondu à cette question, mais j'avais une question similaire et je l'ai trouvée. Je vais donc répondre aux personnes qui envisagent de le faire (à supposer que vous ayez déjà réglé le problème vous-même).

Pour répondre directement à votre question, oui, vous mettez en cache l’image deux fois.

Les appels de téléchargement vers SDWebImageManager mettent automatiquement en mémoire cache les images avec des clés basées sur la chaîne absolue de l'URL de l'image. Si vous voulez votre propre clé, vous pouvez utiliser l'appel de téléchargement sur SDWebImageDownloader qui, autant que je sache, ne met PAS en cache par défaut. À partir de là, vous pouvez appeler sharedImageCache comme vous le faites déjà et mettre en cache avec la clé de votre choix.

Cela dit, il est étrange que vous voyiez des allocations s'accumuler de toute façon, car SDWebImage aime mettre en cache sur le disque et non la mémoire en général. Peut-être que quelque chose d'autre se passe en même temps?

J'espère que cela t'aides,

-Brandon

26
Stakenborg

Dans Swift , utilisez le code ci-dessous pour télécharger une image et la stocker dans le cache:

//SDWebImageManager download image with High Priority 

    SDWebImageManager.sharedManager().downloadImageWithURL(NSURL(string: imageUrl), options: SDWebImageOptions.HighPriority, progress: { (receivedSize :Int, ExpectedSize :Int) in
            SVProgressHUD.show()
            }, completed: { (image :UIImage!, error:NSError!, cacheType :SDImageCacheType, finished :Bool,imageUrl: NSURL!) in
                if(finished) {
                    SVProgressHUD.dismiss()
                    if((image) != nil) {
                        //image downloaded do your stuff
                    }
                }
        })

Swift 3 version:

SDWebImageManager.shared().downloadImage(with: NSURL(string: "...") as URL!, options: .continueInBackground, progress: { 
(receivedSize :Int, ExpectedSize :Int) in

}, completed: { 
(image : UIImage?, error : Error?, cacheType : SDImageCacheType, finished : Bool, url : URL?) in

})

Objective-C version:

[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:imageUrl] options:SDWebImageDownloaderUseNSURLCache progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {

                    if (image && finished) {
                        // Cache image to disk or memory
                        [[SDImageCache sharedImageCache] storeImage:image forKey:CUSTOM_KEY toDisk:YES];     
                    }
                }]; 
16
parth

SDWebImage met en cache l'image à la fois sur le disque et sur la mémoire. Passons par ceci:

  1. Vous téléchargez l'image à partir d'une nouvelle URL.
  2. Il est mis en cache dans la mémoire et sur le disque.
  3. Si vous appelez l'image au cours de la même session, elle est extraite de la mémoire. 
  4. Supposons que vous réexécutiez l'application, puis que vous accédiez à l'URL, elle vérifie la mémoire, où l'image ne sera pas présente, puis vérifie le disque et la récupère. Sinon, il le téléchargera.
  5. L'image reste sur le disque pendant une semaine selon le réglage standard.

Ainsi, vous n'avez pas à vous soucier de la mise en cache. SDWebImage s'en occupe très bien.

Vous pouvez effectuer une mise en œuvre personnalisée pour la mise en cache ainsi qu'une actualisation d'image à partir de la mémoire cache si vous souhaitez également que les paramètres soient conformes à votre en-tête de mise en cache HTTP.

Vous pouvez trouver les détails complets sur leur page github ici .

4
Gautam Jain

Essayez APSmartStorage ( https://github.com/Alterplay/APSmartStorage ) au lieu de SDWebImage. 

APSmartStorage récupère les données du réseau et les met automatiquement en cache sur le disque ou en mémoire de manière intelligible et configurable. Devrait être assez bon pour votre tâche. 

4
slatvick

Essayez ceci pour Swift 4.0

let url = URL(string: imageUrl!)

SDWebImageManager.shared().imageDownloader?.downloadImage(with: url, options: .continueInBackground, progress: nil, completed: {(image:UIImage?, data:Data?, error:Error?, finished:Bool) in
     if image != nil {. 

     }
})
3
reza_khalafi

Swift 4:  

SDWebImageManager.shared().loadImage(
        with: URL(string: imageUrl),
        options: .highPriority,
        progress: nil) { (image, data, error, cacheType, isFinished, imageUrl) in
          print(isFinished)
      }
3
Bogdan Bystritskiy

// CRÉER UNE VUE D'IMAGE PERSONNALISÉE ET PASSER L'URL D'IMAGE PAR ARRAY (INDEXPATH.ROW)

(void) loadImage:(NSString *)imageLink{

    imageLink = [imageLink stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

    SDWebImageManager *manager = [SDWebImageManager sharedManager];

    [manager loadImageWithURL:[NSURL URLWithString:imageLink] options:SDWebImageDelayPlaceholder progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {

    } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {

        imageFrame.image = image;

    }];
}
0
Slimshady

Oui, il est possible de télécharger l'image à l'aide de SDWebImage Et de l'enregistrer dans la mémoire locale Manuellement.

Image téléchargée stocker dans la mémoire locale en utilisant SDWebImage

func saveImage(url: URL, toCache: UIImage?, complation: @escaping SDWebImageNoParamsBlock) {
    guard let toCache = toCache else { return }

    let manager = SDWebImageManager.shared()
    if let key = manager.cacheKey(for: url) {
        manager.imageCache?.store(toCache, forKey: key, completion: complation)
    }
}

Charger une image de la mémoire en utilisant l'URL de l'image

static func imageFromMemory(for url: String) -> UIImage? {
    if let encoded = url.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed),
        let url = URL(string: encoded) {
        let manager = SDWebImageManager.shared()
        if let key: String = manager.cacheKey(for: url),
            let image = manager.imageCache?.imageFromMemoryCache(forKey: key) {
            return image
        }
    }
    return nil
}
0
AshvinGudaliya