web-dev-qa-db-fra.com

Comment charger une image dans Swift avec Alamofire

J'ai un contrôleur de vue de collection, qui charge l'image Async par URL . (Quelque chose comme Instegram) Je cherche le meilleur moyen d'implémenter la partie de l'image de chargement . Dites-moi ce que vous faites pense

Première manière - sans aucune bibliothèque externe:

   let downloadQueue = dispatch_queue_create("com.pro.asyncImages",nil)
    dispatch_async(downloadQueue){

        var data = NSData(contentsOfURL: NSURL(string: pictureUrl!)!)

        var image: UIImage?
        if (data != nil){
            image = UIImage(data: data!)
        }
        dispatch_async(dispatch_get_main_queue()){
            uiImageView.image = image
        }
    }

Deuxième manière - en utilisant Alamofire (la demande appartient à Alamofire)

if let  mediaUrl = info.mediaUrl {
        request(.GET,mediaUrl).response(){
            (_, _, data, _) in
            let image = UIImage(data: data! as NSData)
            imageView.image = image
        }
    }

Et enfin, j'ai lu que AFNetworking, fait un excellent travail en chargeant url async dans urlImage, c'est ce que je veux faire.

AFNetworking est-il donc mieux pour cette tâche? (alors Alamofire) Sinon, je ne comprenais pas comment ajouter AFNetworking à mon projet Swift, en plus de l’ajout du fichier #import “AFNetworking.h”, quels fichiers dois-je ajouter?

s'il vous plaît expliquer quelle méthode est la meilleure, mes besoins sont performance, accusation, mise en cache . le contrôleur de collection de vue agit comme Instegram et charge des images, tout en faisant défiler vers le bas . J'espère avoir été assez clair sur ce dont j'ai besoin Je vous remercie

23
user3728728

Comme le mentionnent les auteurs dans Alamofire README.md :

Quand devrais-je utiliser AFNetworking?

  • Extensions UIKit, telles que le chargement asynchrone d'images dans UIImageView

Alors répondez à votre question:

AFNetworking est-il donc mieux pour cette tâche?

Oui!

Mais si vous voulez toujours utiliser le projet Vanilla Alamofire, vous pouvez récupérer l'image de cette façon:

   Alamofire.request(.GET, "https://robohash.org/123.png").response { (request, response, data, error) in
        self.myImageView.image = UIImage(data: data, scale:1)
    }

P.S.

Mais si vous voulez juste charger une image (bien sûr asynchrone) - vous n'avez pas besoin d'utiliser Alamofire ou AFNetworking .. .. Ajoutez juste cette petite extension dans votre code:

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
                (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                self.image = UIImage(data: data)
            }
        }
    }
}

Et utilisez-le:

myImageView.imageFromUrl("https://robohash.org/123.png")
46
skywinder

J'ai créé une version Swift de UIImageView + AFNetworking ici: Github
Vous ne devez pas utiliser AFNetworking (et un en-tête de pontage) ou Alamofire dans votre projet. Ajoutez simplement le fichier à votre projet et utilisez-le. 


Exemple d'utilisation: 

myImageView.setImageWithUrl(imageUrl, placeHolderImage: somePlaceHolderImage)
17
namanhams

Extrait de Alamofire/README.md

"Afin de garder Alamofire concentré sur les implémentations réseau essentielles, des bibliothèques de composants supplémentaires ont été créées par Alamofire Software Foundation pour apporter des fonctionnalités supplémentaires à l'écosystème d'Alamofire.

AlamofireImage - Bibliothèque d'images comprenant des sérialiseurs de réponse d'image, des extensions UIImage et UIImageView, des filtres d'image personnalisés, un cache en mémoire à purge automatique et un système de téléchargement d'images par priorité. "

https://github.com/Alamofire/AlamofireImage

14
james.ff

Si vous souhaitez utiliser la structure UImageView d’AFNetworking, vous devez utiliser #import "UIImageView+AFNetworking.h" dans votre fichier d’en-tête de pont.

AFNetworking a un cache partagé, vous n’avez donc pas besoin de mettre en cache ou d’annuler manuellement vos demandes. La setImageWithURL d'AFNetworking peut facilement convertir une URL en une image dans ImageView. 

Exemple de code utilisant UIImage+AFNetworking:

cell.imageView.setImageWithURL(NSURL(string:imageSource), placeholderImage: UIImage(named:"placeholder"))

Si vous utilisez Alamofire, vous devez convertir manuellement NSData en UIImage. Pour Alamofire, vous pouvez créer un objet NSCache() pour mettre en cache vos images. Les performances des deux bibliothèques devraient être similaires. Vous pouvez utiliser Alamofire pour les appels d'API de votre serveur, puis utiliser AFNetworking pour afficher des images de manière asynchrone. 

Exemple de code utilisant Alamofire pour le cache d'images:

let imageCache = NSCache()

 if let image = self.imageCache.objectForKey(imageURL) as? UIImage {
    cell.imageView.image = image
  } else {
    // 3
    cell.imageView.image = nil

    // 4
    cell.request = Alamofire.request(.GET, imageURL).validate(contentType: ["image/*"]).responseImage() {
      (request, _, image, error) in
      if error == nil && image != nil {
        // 5
        self.imageCache.setObject(image!, forKey: request.URLString)

        // 6
        if request.URLString == cell.request?.request.URLString {
          cell.imageView.image = image
        }
      } else {
        /*
        If the cell went off-screen before the image was downloaded, we cancel it and
        an NSURLErrorDomain (-999: cancelled) is returned. This is a normal behavior.
        */
      }
    }
  } 

Vous pouvez lire ce tutoriel pour plus de détails sur l’utilisation d’Alamofire.

7
ztan

Voici une approche utilisant RxAlamofire:

import Alamofire
import RxAlamofire

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        requestData(.GET, urlString)
            .observeOn(MainScheduler.instance)
            .subscribeNext { self.image = UIImage(data: $0.1) }
    }
}
6
Lukas Batteau

En fait, il existe plusieurs façons de charger votre image à partir d'une URL à l'aide d'Alamofire . C'est une méthode que j'ai développée et que je l'utilise déjà dans l'un de mes projets Swift. De cette façon, je charge les images de manière asynchrone et les affiche dans UITableView et, du point de vue des performances, tout va bien et il n'y a pas de blocage lors du défilement de UITableView, car le soin d'encaisser les images chargées.

Vous devez d’abord créer une requête GET en utilisant Alamofire pour télécharger l’image, puis utiliser Request + AlamofireImage de la bibliothèque AlamofireImage pour 

import AlamofireImage

Et puis dans 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

}

vous devez appeler votre demande de téléchargement d’image de la manière suivante:

         //Download image
        // We should perform this in a background thread
        Alamofire.request(.GET, deshItem.dish_imageUrl!)
            .responseImage { response in
                debugPrint(response)

                print(response.request)
                print(response.response)
                debugPrint(response.result)

                if let image = response.result.value {
                    print("image downloaded: \(image)")

                    // Store the commit date in to our cache
                    self.ImageCache[dishName!] = image

                    // Update the cell
                    dispatch_async(dispatch_get_main_queue(), {
                        if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                                let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
                                dishImageView.image = image

                        }
                    })

                }
        }

Pour la mise en cache des images, j'ai créé un dictionnaire qui contiendra une image pour chaque cellule ou élément (chaîne). Cette méthode de mise en cache des images évitera ainsi le verrouillage qui apparaît lors du défilement.

Code de l'échantillon complet:

import AlamofireImage

class MainFeedTableViewController: UITableViewController, FloatRatingViewDelegate {

var ImageCache = [String:UIImage]()


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("MainFeedCellID", forIndexPath: indexPath)

    // Configure the cell...

    let dishName = deshItem.dish_name

    //This is a workaround to cash the image and improve the performance while user scrolling UITableView.
    // If this image is already cached, don't re-download
    if let dishImage = ImageCache[dishName!] {
                let dishImageView:UIImageView = cell.viewWithTag(104) as! UIImageView
                dishImageView.image = dishImage
    }
    else {
        //Download image
        // We should perform this in a background thread
        Alamofire.request(.GET, deshItem.dish_imageUrl!)
            .responseImage { response in
                debugPrint(response)

                print(response.request)
                print(response.response)
                debugPrint(response.result)

                if let image = response.result.value {
                    print("image downloaded: \(image)")

                    // Store the commit date in to our cache
                    self.ImageCache[dishName!] = image

                    // Update the cell
                    dispatch_async(dispatch_get_main_queue(), {
                        if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                                let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
                                dishImageView.image = image

                        }
                    })

                }
        }

    }



    return cell
}
4
smapps

Vous pouvez télécharger l'image en utilisant responseData(queue:completionHandler:) 

Swift 4

func downloadImages(imageURL: String) {

    Alamofire.request(imageURL, method: .get)
        .validate()
        .responseData(completionHandler: { (responseData) in
            self.yourImageVIew.image = UIImage(data: responseData.data!) 
            DispatchQueue.main.async {
                // Refresh you views
            }
        })
}
1

J'ai développé une petite et simple bibliothèque CocoaPods pour travailler avec Alamofire et Images.

CocoaPods est un excellent moyen de répondre aux besoins de vos dépendances de bibliothèque. Il est facile à installer une fois, et d'ajouter et de mettre à jour facilement des dépendances dans vos projets.

La bibliothèque est open source et peut être trouvée à https://github.com/gchiacchio/AlamoImage

Il a une excellente documentation avec des exemples, vous pourrez donc en profiter en quelques minutes.

Je travaille moi-même dans quelques projets, notamment des vues de collection et du défilement.

0