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.
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")
(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
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")
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 ;)
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()
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")
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!)
}
}
}
}
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)
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")
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")
, 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:
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
}
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
}
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")
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)
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.
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
}
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!)
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
}
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 }
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é!:)
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)
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()
}
})
utilisez ce code dans Swift
imageView.image=UIImage(data: NSData(contentsOfURL: NSURL(string: "http://myURL/ios8.png")!)!
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
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()
})
}
}
}
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)
}
})
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)
}
})
}
}
}