Chargement / téléchargement d'image à partir de L'URL sur Swift

j'aimerais charger une image à partir d'une URL dans mon application, donc j'ai d'abord essayé avec Objective-C et cela a fonctionné, cependant, avec Swift, j'ai une erreur de compilation:

'imageWithData' n'est pas disponible: utiliser de construction de l'objet 'UIImage(données:)'

ma fonction:

@IBOutlet var imageView : UIImageView

override func viewDidLoad() {
    super.viewDidLoad()

    var url:NSURL = NSURL.URLWithString("http://myURL/ios8.png")
    var data:NSData = NSData.dataWithContentsOfURL(url, options: nil, error: nil)

    imageView.image = UIImage.imageWithData(data)// Error here
}

Dans L'Objectif C:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL *url = [NSURL URLWithString:(@"http://myURL/ios8.png")];
    NSData *data = [NSData dataWithContentsOfURL:url];

    _imageView.image = [UIImage imageWithData: data];
    _labelURL.text = @"http://www.quentinroussat.fr/assets/img/iOS%20icon's%20Style/ios8.png";
 }

est-ce que quelqu'un peut m'expliquer pourquoi le imageWithData: ne fonctionne pas avec Swift, et comment puis-je résoudre le problème.

303
demandé sur Mick MacCallum 2014-06-15 20:27:05

28 réponses

Xcode 8 • Swift 3

synchrone:

if let filePath = Bundle.main.path(forResource: "imageName", ofType: "jpg"), let image = UIImage(contentsOfFile: filePath) {
    imageView.contentMode = .scaleAspectFit
    imageView.image = image
}

asynchrone:

créer une méthode avec un gestionnaire d'achèvement pour obtenir les données d'image à partir de votre url

func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

créer une méthode pour télécharger l'image (démarrer la tâche)

func downloadImage(from url: URL) {
    print("Download Started")
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else { return }
        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        DispatchQueue.main.async() {
            self.imageView.image = UIImage(data: data)
        }
    }
}

Utilisation:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    print("Begin of code")
    if let url = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
        imageView.contentMode = .scaleAspectFit
        downloadImage(from: url)
    }
    print("End of code. The image will continue downloading in the background and it will be loaded when it ends.")
}

Extension :

extension UIImageView {
    func downloaded(from url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
        contentMode = mode
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard
                let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                let data = data, error == nil,
                let image = UIImage(data: data)
                else { return }
            DispatchQueue.main.async() {
                self.image = image
            }
        }.resume()
    }
    func downloaded(from link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
        guard let url = URL(string: link) else { return }
        downloaded(from: url, contentMode: mode)
    }
}

Utilisation:

imageView.downloaded(from: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png")
607
répondu Leo Dabus 2018-08-27 14:27:36

(Swift 4 mise à jour) Pour répondre directement à la question originale, voici l'équivalent swift de L'extrait D'objectif-C affiché.

let url = URL(string: image.url)
let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
imageView.image = UIImage(data: data!)

clause de non-responsabilité:

il est important de noter que la méthode Data(contentsOf:) va télécharger le contenu de l'url de manière synchrone dans le même thread que le code est en cours d'exécution, donc ne pas invoquez ceci dans le fil principal de votre application.

un moyen facile de faire tourner le même code de façon asynchrone, sans bloquer L'interface utilisateur, est d'utiliser GCD:

let url = URL(string: image.url)

DispatchQueue.global().async {
    let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
    DispatchQueue.main.async {
        imageView.image = UIImage(data: data!)
    }
}

cela dit, dans les applications de la vie réelle, si vous voulez avoir la meilleure expérience utilisateur et éviter les téléchargements multiples de la même image, vous pouvez vouloir aussi les avoir non seulement téléchargés, mais mis en cache. Il y a déjà un certain nombre de bibliothèques qui font cela très facilement et ils sont tous vraiment facile à utiliser. Je recommande personnellement Kingfisher :

import Kingfisher

let url = URL(string: "url_of_your_image")
// this downloads the image asynchronously if it's not cached yet
imageView.kf.setImage(with: url) 

Et qu'il

262
répondu Lucas Eduardo 2017-12-18 09:40:55

si vous voulez simplement charger l'image (asynchrone!) - il suffit d'ajouter cette petite extension à votre code swift:

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
                if let imageData = data as NSData? {
                    self.image = UIImage(data: imageData)
                }
            }
        }
    }
}

et l'utiliser de cette façon:

myImageView.imageFromUrl("https://robohash.org/123.png")
63
répondu skywinder 2016-02-01 14:04:19

Swift 2.2 / / Xcode 7.3

je suis des résultats Étonnants !! avec AlamofireImage swift library

il fournit des caractéristiques multiples comme:

  • asynchrone télécharger
  • Auto Purge Image Cache si des avertissements de mémoire se produisent pour l'application
  • "1519200920 URL de l'Image" mise en cache
  • Cache D'Image
  • Éviter Les Téléchargements En Double

et très facile à mettre en œuvre pour votre application

Step.1 Installer des modules


Alamofire 3.3.x

pod "Alamofire"

AlamofireImage 2.4.x

pod 'AlamofireImage '

Step.2 Importation et utilisation 151960920"

import Alamofire
import AlamofireImage

let downloadURL = NSURL(string: "http://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/6.jpg?v=f4b7c5fee820")!
imageView.af_setImageWithURL(downloadURL)

c'est ça!! il s'occupera de tout


grand merci à Alamofire guys , pour faire iDevelopers la vie facile ;)

39
répondu swiftBoy 2016-03-29 14:57:23

Xcode 8 Swift 3

la réponse de Leo Dabus est géniale! Je voulais juste fournir une solution de fonction tout-en-un:

let url = URL(string: 
    "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png")

let task = URLSession.shared.dataTask(with: url!) { data, response, error in
    guard let data = data, error == nil else { return }

    DispatchQueue.main.async() {    // execute on main thread
        self.imageView.image = UIImage(data: data)
    }
}

task.resume()
24
répondu Mark Moeykens 2018-01-31 08:02:01

j'ai enveloppé le code des meilleures réponses à la question dans une seule classe réutilisable prolongeant UIImageView, de sorte que vous pouvez utiliser directement UIImageViews de chargement asynchrone dans votre storyboard (ou les créer à partir de code).

voici ma classe:

import Foundation
import UIKit

class UIImageViewAsync :UIImageView
{

    override init()
    {
        super.init(frame: CGRect())
    }

    override init(frame:CGRect)
    {
        super.init(frame:frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) {
        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in
            completion(data: NSData(data: data))
        }.resume()
    }

    func downloadImage(url:String){
        getDataFromUrl(url) { data in
            dispatch_async(dispatch_get_main_queue()) {
                self.contentMode = UIViewContentMode.ScaleAspectFill
                self.image = UIImage(data: data!)
            }
        }
    }
}

et voici comment l'utiliser:

imageView.downloadImage("http://www.image-server.com/myImage.jpg")
14
répondu datayeah 2015-11-02 14:28:08

pour information : pour swift-2.0 Xcode7.0 beta2

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!)
            }
        }
    }
}
13
répondu katopz 2015-07-13 06:05:55
let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData)
11
répondu user3763002 2014-09-13 01:12:44

Swift 2 avec Gestionnaire d'erreurs et en-tête de demande personnalisée

il suffit D'ajouter extension à UIImageView:

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSMutableURLRequest(URL: url)
            request.setValue("<YOUR_HEADER_VALUE>", forHTTPHeaderField: "<YOUR_HEADER_KEY>")
            NSURLSession.sharedSession().dataTaskWithRequest(request) {
                (data, response, error) in
                guard let data = data where error == nil else{
                    NSLog("Image download error: \(error)")
                    return
                }

                if let httpResponse = response as? NSHTTPURLResponse{
                    if httpResponse.statusCode > 400 {
                        let errorMsg = NSString(data: data, encoding: NSUTF8StringEncoding)
                        NSLog("Image download error, statusCode: \(httpResponse.statusCode), error: \(errorMsg!)")
                        return
                    }
                }

            dispatch_async(dispatch_get_main_queue(), {
                NSLog("Image download success")
                self.image = UIImage(data: data)
            })
            }.resume()
        }
    }
}

et ensuite, utilisez le nouveau imageFromUrl(urlString: String) pour télécharger l'image

Utilisation:

imageView.imageFromUrl("https://i.imgur.com/ONaprQV.png")
7
répondu Cody 2016-06-22 05:07:49

swift 3 avec traitement des erreurs

let url = URL(string: arr[indexPath.row] as! String)
if url != nil {
    DispatchQueue.global().async {
        let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
        DispatchQueue.main.async {
            if data != nil {
                cell.imgView.image = UIImage(data:data!)
            }else{
                cell.imgView.image = UIImage(named: "default.png")
            }
        }
    }
}

Avec Extension

extension UIImageView {

    func setCustomImage(_ imgURLString: String?) {
        guard let imageURLString = imgURLString else {
            self.image = UIImage(named: "default.png")
            return
        }
        DispatchQueue.global().async {
            let data = try? Data(contentsOf: URL(string: imageURLString)!)
            DispatchQueue.main.async {
                self.image = data != nil ? UIImage(data: data!) : UIImage(named: "default.png")
            }
        }
    }
}

L'Extension De L'Utilisation De La

myImageView. setCustomImage ("url")

7
répondu Manee ios 2018-04-12 12:30:51

, Vous aurez envie de le faire:

UIImage(data: data)

dans Swift, ils ont remplacé la plupart des méthodes D'usine Objective C par des constructeurs réguliers.

voir:

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_26

6
répondu joshstaiger 2014-06-15 16:51:15

Swift 4

cette méthode va télécharger une image d'un site Web asynchrone et la mettre en cache:

    func getImageFromWeb(_ urlString: String, closure: @escaping (UIImage?) -> ()) {
        guard let url = URL(string: urlString) else {
return closure(nil)
        }
        let task = URLSession(configuration: .default).dataTask(with: url) { (data, response, error) in
            guard error == nil else {
                print("error: \(String(describing: error))")
                return closure(nil)
            }
            guard response != nil else {
                print("no response")
                return closure(nil)
            }
            guard data != nil else {
                print("no data")
                return closure(nil)
            }
            DispatchQueue.main.async {
                closure(UIImage(data: data!))
            }
        }; task.resume()
    }

en usage:

    getImageFromWeb("http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") { (image) in
        if let image = image {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
            imageView.image = image
            self.view.addSubview(imageView)
        } // if you use an Else statement, it will be in background
    }
6
répondu Bobby 2017-11-27 13:30:32

Swift 4: un chargeur simple pour les petites images (ex: vignettes) qui utilise NSCache et fonctionne toujours sur le fil principal:

class ImageLoader {

  private static let cache = NSCache<NSString, NSData>()

  class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {

      if let data = self.cache.object(forKey: url.absoluteString as NSString) {
        DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
        return
      }

      guard let data = NSData(contentsOf: url) else {
        DispatchQueue.main.async { completionHandler(nil) }
        return
      }

      self.cache.setObject(data, forKey: url.absoluteString as NSString)
      DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
    }
  }

}

Utilisation:

ImageLoader.image(for: imageURL) { image in
  self.imageView.image = image
}
6
répondu fethica 2018-07-23 17:44:37

Swift 2.0:

1)

if let url = NSURL(string: "http://etc...") {
    if let data = NSData(contentsOfURL: url) {
        imageURL.image = UIImage(data: data)
    }        
}

ou

imageURL.image =
    NSURL(string: "http:// image name...")
    .flatMap { NSData(contentsOfURL: "151910920") }
    .flatMap { UIImage(data: "151910920") }

2) Ajouter cette méthode à VC ou Extension.

func load_image(urlString:String)
{   let imgURL: NSURL = NSURL(string: urlString)!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in

        if error == nil {
            self.image_element.image = UIImage(data: data)
        }
    }
}

Utilisation :

self.load_image(" url strig here")
5
répondu A.G 2016-02-17 05:31:57

Kingfisher est l'une des meilleures bibliothèques pour charger L'image dans L'URL.

GitHub URL - https://github.com/onevcat/Kingfisher

// If you want to use Activity Indicator.
imageview_pic.kf.indicatorType = .activity
imageview_pic.kf.setImage(with: URL(string: "Give your url string"))

// If you want to use custom placeholder image.
imageview_pic.kf.setImage(with: URL(string: "Give your url string"), placeholder: UIImage(named: "placeholder image name"), options: nil, progressBlock: nil, completionHandler: nil)
4
répondu Kamani Jasmin 2018-06-11 23:28:43

une méthode pour obtenir l'image qui est sûre et fonctionne avec Swift 2.0 et X-Code 7.1:

static func imageForImageURLString(imageURLString: String, completion: (image: UIImage?, success: Bool) -> Void) {
    guard let url = NSURL(string: imageURLString),
        let data = NSData(contentsOfURL: url),
        let image = UIImage(data: data)
        else { 
            completion(image: nil, success: false); 
            return 
       }

    completion(image: image, success: true)
}

vous appelleriez alors cette méthode comme ceci:

imageForImageURLString(imageString) { (image, success) -> Void in
        if success {
            guard let image = image 
                 else { return } // Error handling here 
            // You now have the image. 
         } else {
            // Error handling here.
        }
    }

si vous mettez à jour la vue avec l'image, vous devrez l'utiliser après le" if success { " :

    dispatch_async(dispatch_get_main_queue()) { () -> Void in
         guard let image = image 
              else { return } // Error handling here 
         // You now have the image. Use the image to update the view or anything UI related here
         // Reload the view, so the image appears
    }

la raison pour laquelle cette dernière partie est nécessaire si vous utilisez l'image dans L'UI est parce que les appels réseau prennent du temps. Si vous essayez de mettre à jour le L'INTERFACE utilisateur à l'aide de l'image sans appel dispatch_async comme ci-dessus, l'ordinateur va chercher l'image, si l'image est encore récupérée, trouver qu'il n'y est pas d'image (encore), et d'avancer comme s'il n'y avait aucune image trouvé. Mettre votre code à l'intérieur d'une fermeture de Completion dispatch_async dit à l'ordinateur: "allez, récupérez cette image et quand vous avez terminé, remplissez ce code."De cette façon, vous aurez l'image lorsque le code est appelé et tout fonctionne bien.

3
répondu Ben Patch 2015-12-08 17:28:52

si vous recherchez une implémentation très simple. (Cela a fonctionné pour moi dans Swift 2)

 let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")
 let imagedData = NSData(contentsOfURL: imageURL!)!
 imageView?.image = UIImage(data: imagedData)

j'ai implémenté dans une tableview avec une cellule personnalisée qui n'a qu'une image

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

        let cell = tableView.dequeueReusableCellWithIdentifier("theCell", forIndexPath: indexPath) as! customTableViewCell

        let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")

        let imagedData = NSData(contentsOfURL: imageURL!)!

        cell.imageView?.image = UIImage(data: imagedData)

        return cell

    }
3
répondu Naishta 2016-04-27 21:58:58

la seule chose qui manque est a !

let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData!)
1
répondu Simon Jensen 2014-11-03 13:00:57

Swift 2.x réponse qui télécharge l'image dans un fichier (par opposition à la réponse de Leo Dabus, qui stocke l'image en mémoire). Basé sur la réponse de Leo Dabus et la réponse de Rob de obtenir les données de NSURLSession DownloadTaskWithRequest de completion handler :

    // Set download vars
    let downloadURL = NSURL() // URL to download from
    let localFilename = "foobar.png" // Filename for storing locally 

    // Create download request
    let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in
        guard location != nil && error == nil else {
            print("Error downloading message: \(error)")
            return
        }

        // If here, no errors so save message to permanent location
        let fileManager = NSFileManager.defaultManager()
        do {
            let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            let fileURL = documents.URLByAppendingPathComponent(localFilename)
            try fileManager.moveItemAtURL(location!, toURL: fileURL)
            self.doFileDownloaded(fileURL, localFilename: localFilename)
            print("Downloaded message @ \(localFilename)")
        } catch {
            print("Error downloading message: \(error)")
        }
    }

    // Start download
    print("Starting download @ \(downloadURL)")
    task.resume()


// Helper function called after file successfully downloaded
private func doFileDownloaded(fileURL: NSURL, localFilename: String) {

    // Do stuff with downloaded image

}
1
répondu Crashalot 2017-05-23 12:02:46

voici le code de travail pour le chargement / téléchargement D'image à partir D'URL. NSCache automatiquement et afficher L'image Placeholder avant le téléchargement et charger L'image réelle (Code Swift 4).

func NKPlaceholderImage(image:UIImage?, imageView:UIImageView?,imgUrl:String,compate:@escaping (UIImage?) -> Void){

    if image != nil && imageView != nil {
        imageView!.image = image!
    }

    var urlcatch = imgUrl.replacingOccurrences(of: "/", with: "#")
    let documentpath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    urlcatch = documentpath + "/" + "\(urlcatch)"

    let image = UIImage(contentsOfFile:urlcatch)
    if image != nil && imageView != nil
    {
        imageView!.image = image!
        compate(image)

    }else{

        if let url = URL(string: imgUrl){

            DispatchQueue.global(qos: .background).async {
                () -> Void in
                let imgdata = NSData(contentsOf: url)
                DispatchQueue.main.async {
                    () -> Void in
                    imgdata?.write(toFile: urlcatch, atomically: true)
                    let image = UIImage(contentsOfFile:urlcatch)
                    compate(image)
                    if image != nil  {
                        if imageView != nil  {
                            imageView!.image = image!
                        }
                    }
                }
            }
        }
    }
}

utiliser comme ceci:

// Here imgPicture = your imageView
// UIImage(named: "placeholder") is Display image brfore download and load actual image. 

NKPlaceholderImage(image: UIImage(named: "placeholder"), imageView: imgPicture, imgUrl: "Put Here your server image Url Sting") { (image) in }
1
répondu Nikunj Kumbhani 2018-08-08 12:32:41
class func downloadImageFromUrl(with urlStr: String, andCompletionHandler:@escaping (_ result:Bool) -> Void) {
        guard let url = URL(string: urlStr) else {
            andCompletionHandler(false)
            return
        }
        DispatchQueue.global(qos: .background).async {
            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
                if error == nil {
                    let httpURLResponse = response as? HTTPURLResponse
                    Utils.print( "status code ID : \(String(describing: httpURLResponse?.statusCode))")
                    if httpURLResponse?.statusCode == 200 {
                        if let data = data {
                            if let image = UIImage(data: data) {
                                ImageCaching.sharedInterface().setImage(image, withID: url.absoluteString as NSString)
                                DispatchQueue.main.async {
                                    andCompletionHandler(true)
                                }
                            }else {
                                andCompletionHandler(false)
                            }
                        }else {
                            andCompletionHandler(false)
                        }
                    }else {
                        andCompletionHandler(false)
                    }
                }else {
                    andCompletionHandler(false)
                }
            }).resume()
        }
    }

j'ai créé une fonction de classe simple dans ma classe Utils.swift pour appeler cette méthode vous pouvez simplement accéder par classname.methodname et vos images sont enregistrées dans NSCache en utilisant ImageCaching.swift classe

Utils.downloadImageFromUrl(with: URL, andCompletionHandler: { (isDownloaded) in
                            if isDownloaded {
                                if  let image = ImageCaching.sharedInterface().getImage(URL as NSString) {
                                    self.btnTeam.setBackgroundImage(image, for: .normal)
                                }
                            }else {
                                DispatchQueue.main.async {
                                    self.btnTeam.setBackgroundImage(#imageLiteral(resourceName: "com"), for: .normal)
                                }
                            }
                        })

Heureux Codding. Santé!:)

1
répondu Vishal16 2018-09-11 08:44:49

Swift 4: :

cela affichera chargeur lors du chargement de l'image. Vous pouvez utiliser NSCache qui stockent l'image Temporairement

let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
    func loadImageUsingCache(withUrl urlString : String) {
        let url = URL(string: urlString)
        if url == nil {return}
        self.image = nil

        // check cached image
        if let cachedImage = imageCache.object(forKey: urlString as NSString)  {
            self.image = cachedImage
            return
        }

        let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: .gray)
        addSubview(activityIndicator)
        activityIndicator.startAnimating()
        activityIndicator.center = self.center

        // if not, download image from url
        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                if let image = UIImage(data: data!) {
                    imageCache.setObject(image, forKey: urlString as NSString)
                    self.image = image
                    activityIndicator.removeFromSuperview()
                }
            }

        }).resume()
    }
}

Usage: -

truckImageView.loadImageUsingCache(withUrl: currentTruck.logoString)
1
répondu Jack 2018-09-14 10:45:53

je recommande D'utiliser la bibliothèque Kingfisher pour télécharger des images de manière asynchrone. La meilleure partie sur L'utilisation de Kingfisher est, il cache toutes les images téléchargées par défaut avec l'url de l'image comme un id. La prochaine fois que vous demandez de télécharger l'image avec cette URl particulière, il le chargera à partir de cache.

Utilisation:

newsImage.kf.setImage(with: imageUrl!, placeholder: nil, options: nil, progressBlock: nil, completionHandler: { (image, error, cacheType, imageUrl) in
                if error == nil{
                    self.activityIndicator.stopAnimating()
                }else if error != nil{
                    self.activityIndicator.stopAnimating()
                }
            })
1
répondu Raj Salla 2018-09-27 10:23:17

utilisez ce code dans Swift

imageView.image=UIImage(data: NSData(contentsOfURL: NSURL(string: "http://myURL/ios8.png")!)!
0
répondu Bibin Joseph 2016-04-19 10:56:58

utilisation D'Ascyimageview vous pouvez facilement charger imageurl dans imageview.

laissez image1Url:URL = URL(string: "(imageurl)" comme une Chaîne de caractères)! imageview.imageURL = image1Url

0
répondu saurabh rathod 2018-07-05 11:36:42

Swift 4.1 j'ai créé une fonction qui passe juste l'url de l'image, la clé de cache après que l'image est générée, la définit au bloc d'achèvement.

   class NetworkManager: NSObject {

  private var imageQueue = OperationQueue()
  private var imageCache = NSCache<AnyObject, AnyObject>()

  func downloadImageWithUrl(imageUrl: String, cacheKey: String, completionBlock: @escaping (_ image: UIImage?)-> Void) {

    let downloadedImage = imageCache.object(forKey: cacheKey as AnyObject)
    if let  _ = downloadedImage as? UIImage {
      completionBlock(downloadedImage as? UIImage)
    } else {
      let blockOperation = BlockOperation()
      blockOperation.addExecutionBlock({
        let url = URL(string: imageUrl)
        do {
          let data = try Data(contentsOf: url!)
          let newImage = UIImage(data: data)
          if newImage != nil {
            self.imageCache.setObject(newImage!, forKey: cacheKey as AnyObject)
            self.runOnMainThread {
              completionBlock(newImage)
            }
          } else {
            completionBlock(nil)
          }
        } catch {
          completionBlock(nil)
        }
      })
      self.imageQueue.addOperation(blockOperation)
      blockOperation.completionBlock = {
        print("Image downloaded \(cacheKey)")
      }
    }
  }
}
extension NetworkManager {
  fileprivate func runOnMainThread(block:@escaping ()->Void) {
    if Thread.isMainThread {
      block()
    } else {
      let mainQueue = OperationQueue.main
      mainQueue.addOperation({
        block()
      })
    }
  }
}
0
répondu GSK 2018-08-19 14:53:53

vous pouvez utiliser pod SDWebImage pour obtenir le même. Il est facile à utiliser. Vous pouvez obtenir des documents ici SDWebImage

voici le code d'échantillon

self.yourImage.sd_setImage(with: NSURL(string: StrUrl as String ) as URL!, placeholderImage: placeholderImage, options: SDWebImageOptions(rawValue: 0), completed: { (image, error, cacheType, imageURL) in
                if( error != nil)
                {
                    print("Error while displaying image" , (error?.localizedDescription)! as String)
                }
            })
0
répondu Shruti Thombre 2018-10-10 10:21:42

pour Swift-3 et plus:

extension UIImageView {
  public func imageFromUrl(urlString: String) {
    if let url = URL(string: urlString) {
        let request = URLRequest(url: url)
        NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: .main, completionHandler: { (response, data, error) in
            if let imageData = data as NSData? {
                self.image = UIImage(data: imageData as Data)
            }
        })
    }
  }
}
-1
répondu FARAZ 2017-06-15 11:24:46