Swift'te URL'den resim yükleme / indirme


413

Uygulamamdaki bir URL'den resim yüklemek istiyorum, bu yüzden önce Objective-C ile denedim ve işe yaradı, ancak Swift ile bir derleme hatası aldım:

'imageWithData' kullanılamıyor: 'UIImage (data :)' nesne yapısını kullan

Benim fonksiyonum:

@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
}

Hedef-C'de:

- (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";
 }

Birisi bana imageWithData:Swift'in neden çalışmadığını ve sorunu nasıl çözebileceğimi açıklayabilir mi ?


3
Bunu deneyinimageURL.image = UIImage(data: myDataVar)
aleclarson

Mükemmel çalıştı! Teşekkür ederim Ancak bu yöntemin neden Swift'te değil, Objective C'de çalıştığını anlamıyorum ... Strange
QuentR

Bir Cocoa sınıfıyla ilgili sorun yaşarsanız, sınıf adını tıklatarak CMD + 'yı deneyin ve sınıf için Swift arayüzünü görebilmeniz gerekir!
aleclarson

3
if let url = NSURL (dize: "imageurl") {if let veri = NSData (contentOfURL: url) {imageView.image = UIImage (veri: veri)}}
Hardik Bar

2
@Leo Dabus Bu soru Swift 2 ile ilgili değildir. Lütfen etiketi eklemeyi bırakın.
Mick MacCallum

Yanıtlar:


769

Xcode 8 veya üstü • ​​Swift 3 veya üstü

Eş zamanlı:

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

uyumsuz:

URL'nizden resim verilerini almak için bir tamamlayıcı işleyici ile bir yöntem oluşturun

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

Görüntüyü indirmek için bir yöntem oluşturun (görevi başlatın)

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() { [weak self] in
            self?.imageView.image = UIImage(data: data)
        }
    }
}

Kullanımı:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    print("Begin of code")
    let url = URL(string: "https://cdn.arstechnica.net/wp-content/uploads/2018/06/macOS-Mojave-Dynamic-Wallpaper-transition.jpg")! 
    downloadImage(from: url)
    print("End of code. The image will continue downloading in the background and it will be loaded when it ends.")
}

Uzantı :

extension UIImageView {
    func downloaded(from url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {  // for swift 4.2 syntax just use ===> mode: UIView.ContentMode
        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() { [weak self] in
                self?.image = image
            }
        }.resume()
    }
    func downloaded(from link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {  // for swift 4.2 syntax just use ===> mode: UIView.ContentMode
        guard let url = URL(string: link) else { return }
        downloaded(from: url, contentMode: mode)
    }
}

Kullanımı:

imageView.downloaded(from: "https://cdn.arstechnica.net/wp-content/uploads/2018/06/macOS-Mojave-Dynamic-Wallpaper-transition.jpg")

13
Burada sadece bir yan not, ona ilişkili bir nesne ayarlamanız gerekir; Aksi takdirde görüntüleri üst üste yükleyebilirsiniz. Örneğin, UITableViewhücrenin bir görüntüyü gösterdiği ve ayrıştırılmış hücre döndürüldüğünde görüntü güncellenir. İşlem # 1 daha uzun sürüyorsa işlem # 2, işlem # 2 görüntüsünü gösterecek ve daha sonra bu görüntü kullanıcı için geçerli olmasa bile işlem # 1 tarafından güncellenecektir.
Paul Peelen

1
Bu benim sorunumu çözdü. Tablo görünümünde url ile resim yüklemeye çalıştığımda, yukarı veya aşağı kaydırdığınızda kaydırma görünümü gerçekten yanıt vermiyor. UIImageView Uzantısını kullandım ve sorunumu çözdü. Teşekkürler.
JengGe Chao

1
@LeoDabus tamam teşekkürler. ve SO ile ilgili birçok soruyu cevapladığınız için teşekkürler! hızlı ve iOS profesörü gibisiniz. :)
Crashalot

2
@LeoDabus nasıl downloadTaskWithURL yerine dataTaskWithURL kullandınız?
Crashalot

3
Birincisi ikincisini bir dosyaya
hafızaya indirir

349

(Swift 4 güncellemesi) Orijinal soruyu doğrudan cevaplamak için, yayınlanan Objective-C snippet'inin hızlı karşılığı.

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!)

YASAL UYARI:

Data(contentsOf:)Yöntemin, URL'nin içeriğini kodun yürütülmekte olduğu aynı iş parçacığında eşzamanlı olarak indireceğini unutmayın , bu nedenle bunu uygulamanızın ana iş parçacığında çağırmayın.

Aynı kodu, kullanıcı arayüzünü engellemeden senkronize olmayan bir şekilde çalıştırmanın kolay bir yolu GCD kullanmaktır:

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!)
    }
}

Bununla birlikte, gerçek yaşam uygulamalarında, en iyi Kullanıcı Deneyimi'ne sahip olmak ve aynı görüntünün birden fazla indirilmesini önlemek istiyorsanız, bunların yalnızca indirilmesini değil, aynı zamanda önbelleğe alınmasını da isteyebilirsiniz. Bunu çok sorunsuz yapan zaten birkaç kütüphane var ve hepsinin kullanımı gerçekten kolay. Şahsen Kingfisher tavsiye :

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) 

Ve bu kadar


12
"Kolayca" sübjektiftir ve acemi kodlayıcılar bu istenmeyen davranışı beklemez, ancak bu kopyayı olduğu gibi kopyala / yapıştır. Belki cevabınızı güncelleyebilirsiniz?
Orlin Georgiev

13
Hala aynı fikirde değilim. Bazı cevaplar basit tutulmalıdır, buraya gelen birçok kişi küçük kod snippet'lerini kopyalayıp yapıştırmayı sever. Swift'ten orijinal sorudan obj-C kodunu tercüme ettim, bunun dışında her şey bir bonus. Ve bu arada, aynı soruda bu tür bonus bilgileri sağlayan bir cevap zaten var, bu da bilgiyi çoğaltmak için daha az mantıklı.
Lucas Eduardo

1
@ Kullanıcı sadece image.urlherhangi bir dize url, sabit kodlu veya değil ile değiştirin :)
Lucas Eduardo

1
@IanWarburton Tabii ki ne istersen kullanabilirsiniz :). 1) Bu cevap, objektif-C'de aynı yaklaşımı kullanan orijinal soruya dayanmaktadır, bu yüzden sadece "çeviride" hızlı bir şekilde yardımcı oldum. 2) Bu yaklaşımı kaldırmak ve koymak mantıklı değil URLSession.dataTaskçünkü burada diğer birçok cevap nasıl yapılacağını gösteriyor, Farklı seçenekleri açık tutmak daha iyidir.
Lucas Eduardo

2
Heyo, önerilen çerçeve, yalıçapkını, cevap olarak belirtildiği gibi tüm ağır kaldırma yapacağız. Önerin için teşekkürler!
1919'da Kilmazing

68

Sadece görüntüyü yüklemek istiyorsanız (Eşzamansız olarak!) - bu küçük uzantıyı hızlı kodunuza ekleyin:

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)
                }
            }
        }
    }
}

Ve şu şekilde kullanın:

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

1
Görünmüyor ve bence GCD'ye ihtiyaç var. Nasıl yenileyebilirim?
jo3birdtalk

@ jo3birdtalk bu bir GCD sorunu değil. Bağlantılarınızı manzara ile kontrol edin.
skywinder

6
NSURLConnection, iOS 9'da kullanılmıyor vb. NSURLSession intead kullanın.
muhasturk

2
sendAsynchronousRequest, iOS 9
Crashalot'ta

Teşekkür skywinder, diziden görüntüleri indirmek için bu yöntemi kullanıyorum. Kullanıcı düğmesine cancelbastığında indirme işlemini durdurmasını istiyorum . Bu yöntemi kullanarak bunu nasıl yapabilirim hakkında bir fikrin var mı? İptal işlevselliği eklemem gerekiyor.
ZAFAR007

44

Swift 2.2 || Xcode 7.3

İnanılmaz sonuçlar aldım !! ile AlamofireImage hızlı kitaplığında

Gibi birçok özellik sunar:

  • Eşzamansız olarak indir
  • Uygulama için bellek uyarıları olursa Görüntü Önbelleği Otomatik Olarak Boşaltma
  • Resim URL'si önbelleğe alma
  • Görüntü Önbellekleme
  • Yinelenen İndirmelerden Kaçının

ve uygulamanız için uygulanması çok kolay

Adım.1 Bölmeleri yükleme


Alamofire 3.3.x

'Alamofire' bölmesi

Görüntü 2.4.x

'AlamofireImage' bölmesi

Adım 2 içe aktarma ve kullanma

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)

bu kadar!! her şeyle ilgilenecek


İDevelopers'ın hayatını kolaylaştırdığı için Alamofire adamlarına çok teşekkürler ;)


8
Swift 3: foregroundImage.af_setImage (ileURL: URL olarak downloadURL)
thejuki

28

Xcode 8Hızlı 3

Leo Dabus'un cevabı harika! Sadece hepsi bir arada bir işlev çözümü sunmak istedim:

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()

3
Mark, muhtemelen sonunda "async" demekti
Fattie

16

Soruya en iyi cevapların kodunu UIImageView'ı genişleten tek, yeniden kullanılabilir bir sınıfa sardım, böylece doğrudan film şeridinizde eşzamansız yükleme UIImageViews'i kullanabilirsiniz (veya koddan oluşturabilirsiniz).

İşte benim sınıfım:

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!)
            }
        }
    }
}

ve işte nasıl kullanılacağı:

imageView.downloadImage("http://www.image-server.com/myImage.jpg")

2
Gerçekten geçersiz kılınan initlere ihtiyacımız var mı? Zaten inits miras alınmıyor mu? Görünüşe göre burada sadece kendisinin üzerinde süper demek için geçersiz kılıyoruz, bu da bana fazlalık gibi geliyor.
NYC Teknik Mühendisi

16

Hızlı 4 ::

Bu, görüntüyü yüklerken yükleyiciyi gösterir. Görüntüyü geçici olarak saklayan NSCache'i kullanabilirsiniz

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()
    }
}

Kullanımı: -

truckImageView.loadImageUsingCache(withUrl: currentTruck.logoString)

1
İşe yarıyor. Hata durumunda da eventIndicator kaldırma işlemini kopyalayın.
djdance

1
projem için çok faydalı.
partikles

13
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)

5
fatal error: unexpectedly found nil while unwrapping an Optional value
Kullanıcı

Eşzamansız bir şey yazma şansınız var mı?
Jed Grant

@JedGrant, başka bir iş parçacığına ve geri aramaya girmek için dispatch_async kullanabilirsiniz
Matej

NSData bir "!" (sonunda!) dikkat edin: var imageData: NSData = NSData (contentOfURL: url, options: NSDataReadingOptions.DataReadingMappedIfSafe, hata: & err)!
botbot

13

FYI: swift-2.0 Xcode7.0 beta2 için

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!)
            }
        }
    }
}

5
NSURLConeksiyonu kesilir. NSURLSession kullanmak zorundasınız. Swift 2.0 ve Xcode 7 ile kodlamak daha iyidir
BilalReffas

11

hata işleme ile swift 3

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")
            }
        }
    }
}

Uzatmalı

extension UIImageView {

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

Uzantı Kullanımı

myImageView. setCustomImage("url")

Önbellek desteği ile

let imageCache = NSCache<NSString, UIImage>()

extension UIImageView {

    func loadImageUsingCacheWithURLString(_ URLString: String, placeHolder: UIImage?) {

        self.image = nil
        if let cachedImage = imageCache.object(forKey: NSString(string: URLString)) {
            self.image = cachedImage
            return
        }

        if let url = URL(string: URLString) {
            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

                //print("RESPONSE FROM API: \(response)")
                if error != nil {
                    print("ERROR LOADING IMAGES FROM URL: \(String(describing: error))")
                    DispatchQueue.main.async { [weak self] in
                        self?.image = placeHolder
                    }
                    return
                }
                DispatchQueue.main.async { [weak self] in
                    if let data = data {
                        if let downloadedImage = UIImage(data: data) {
                            imageCache.setObject(downloadedImage, forKey: NSString(string: URLString))
                            self?.image = downloadedImage
                        }
                    }
                }
            }).resume()
        }
    }
}

9

Swift 4: NSCache kullanan ve her zaman ana iş parçacığında çalışan küçük resimler (örn: küçük resimler) için basit bir yükleyici:

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)) }
    }
  }

}

Kullanımı:

ImageLoader.image(for: imageURL) { image in
  self.imageView.image = image
}

Neden singleton'u struct ile kullanmalıyım? Bu Sınıfınız NSCache ilgili sorunlara neden olabilir hangi değişmez olmasına neden olur
XcodeNOOB

Bunu işaret ettiğiniz için teşekkür ederim, sadece olarak değiştirdim class.
fethica

1
özel izin önbellek bana hata veriyordu böylece statik değişti ve çalıştı! Teşekkürler
Hammad Tarık

7

Yapmak isteyeceksiniz:

UIImage(data: data)

Swift'te, çoğu Objective C fabrika yöntemini normal kurucularla değiştirdiler.

Görmek:

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


2
Teknik olarak eşleştirildi, değiştirilmedi. Kendi yönteminizi +(instancetype)[MyThing thingWithOtherThing:]yaparsanız MyThing(otherThing: ...), Swift'teki gibi de adlandırırsınız.
Brian Nickel

7

Hata Tutamaçlı ve özel istek üstbilgili Swift 2

UIImageView'a uzantı eklemeniz yeterlidir:

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()
        }
    }
}

Ve sonra, imageFromUrl(urlString: String)resmi indirmek için yenisini kullanın

Kullanımı:

imageView.imageFromUrl("https://i.imgur.com/ONaprQV.png")

hızlı 3'te, bu hatayı almaya devam ediyorum. Sorun ne ? Bu satırda "" "URLSession.shared.dataTask (ile: url) {" "" "" "" "'dataTask' türünde bir argüman listesiyle (data :, URLResponse ?, Hata? ) -> Geçersiz) '
Aymen BRomdhane

7

Hızlı 4

Bu yöntem, bir web sitesinden bir resmi eşzamansız olarak indirir ve önbelleğe alır:

    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()
    }

Kullanımda:

    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
    }

Önbellek nasıl? Ve ne kadar süreyle?
Ramis

Kalıcı olarak depolanmış gibi görünüyor, ki bu garip, Kütüphane> Önbellekler klasöründe saklanıyor. Simülatörde çalıştırıldığında bilgisayarınızda bu konuma ulaşmak için print (NSHomeDirectory ()) kullanın.
Bobby

5

Swift 2.0:

1)

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

VEYA

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

2) Bu yöntemi VC veya Uzantıya ekleyin.

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)
        }
    }
}

Kullanımı:

self.load_image(" url strig here")

sendAsynchronousRequest iOS 9
Crashalot'ta

5

Kingfisher, URL'ye resim yüklemek için en iyi kütüphanelerden biridir.

Github URL'si - 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)

5

URL'den resim yüklemek / indirmek için çalışma kodu. NSCache otomatik olarak indirin ve indirmeden önce Yer Tutucu görüntüsünü görüntüleyin ve Gerçek görüntüyü yükleyin (Swift 4 Kodu).

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!
                        }
                    }
                }
            }
        }
    }
}

Bunun gibi kullanın:

// 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
Benimle çalışan tek kişi. benim sorunum müzik çalar uygulamak oldu ve ben de telefon kapatıldığında ve işleyici UIImage türünü alır bu yüzden bu yöntemi kullanmak zorunda bildirimde yüklemek için görüntü istedim oldu.
JhonnyTawk

4

Swift 2.0 ve X-Code 7.1 ile güvenli olan ve görüntüyü elde etmek için bir yöntem:

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)
}

Daha sonra bu yöntemi şöyle çağırırsınız:

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.
        }
    }

Görünümü resimle güncelliyorsanız, bunu "if başarılı {" dan sonra kullanmanız gerekir:

    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
    }

Kullanıcı arayüzünde görüntüyü kullanıyorsanız bu son bölümün gerekli olmasının nedeni, ağ çağrılarının zaman almasıdır. Yukarıdaki gibi dispatch_async çağırmadan görüntüyü kullanarak kullanıcı arayüzünü güncellemeye çalışırsanız, bilgisayar görüntü hala getirilirken görüntüyü arayacak, görüntü olmadığını (henüz) bulunacak ve görüntü yokmuş gibi ilerleyecektir bulundu. Kodunuzu bir dispatch_async tamamlama kapatmasının içine koymak, bilgisayara "Git, bu resmi alın ve işiniz bittiğinde bu kodu tamamlayın" diyor. Bu şekilde, kod çağrıldığında görüntüye sahip olursunuz ve işler iyi çalışır.


4

Çok çok basit bir uygulama arıyorsanız. (Bu benim için Swift 2'de çalıştı)

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

Yalnızca görüntü içeren özel bir hücre içeren bir tablo görünümünde uyguladım

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

    }

haklısın, thats çünkü indirme ve sıkıştırma ana iş parçacığında gerçekleşiyor. ideal olarak bir arka plan iş parçacığında bu 2 adımı eşzamansız olarak yapmalısınız, dispatch_async global kuyruğu kullanıyor olabilir
Naishta

Evet, arka plan iş parçacığını kullanarak indirme hızını optimize edebiliriz ve gerekirse bunun yerine mantığı değiştirebiliriz sdWebImage veya başka bir çerçeve kullanabiliriz.
Gourav Joshi

2

Görüntüleri eşzamansız olarak indirmek için Kingfisher kütüphanesini kullanmanızı tavsiye ederim. Kingfisher'ı kullanmanın en iyi yanı, indirilen tüm resimleri varsayılan olarak resim URL'si ile birlikte kimlik olarak önbelleğe almaktır. Bir dahaki sefere belirli bir URl ile görüntü indirmek istediğinizde, görüntüyü önbellekten yükler.

Kullanımı:

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()
                }
            })

2

SDWebImageAynı şeyi elde etmek için bölmeyi kullanabilirsiniz . Kullanımı kolaydır. Sen burada belgesel alabilirsiniz SDWebImage

İşte örnek kod

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)
                }
            })

2

hızlı 5

extension UIImageView {
    func load(url: URL) {
        DispatchQueue.global().async { [weak self] in
            if let data = try? Data(contentsOf: url) {
                if let image = UIImage(data: data) {
                    DispatchQueue.main.async {
                        self?.image = image
                    }
                }
            }
        }
    }
}

kullanmak için

override func awakeFromNib() {
    super.awakeFromNib()
    imgView.load(url: "<imageURLHere>")
}

1

Eksik olan tek şey bir!

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!)

Geç cevap için özür dilerim, hangi hataları aldığınız konusunda daha kesin olabilir misiniz?
Simon Jensen

1

Görüntüyü dosyaya indiren Swift 2.x yanıtı (görüntüyü hafızada saklayan Leo Dabus'un cevabının aksine). Leo Dabus'un cevabına ve Rob'un NSURLSession'dan veri al cevabına dayanarak DownloadTaskWithRequest'i tamamlama işleyicisinden alın :

    // 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

Swift 4.1 Ben sadece görüntü url geçmek bir fonksiyon sandık var, görüntü oluşturulduktan sonra önbellek anahtarı tamamlama bloğu olarak ayarlayın.

   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()
      })
    }
  }
}

1
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()
        }
    }

Ben Utils.swiftsadece tarafından erişebilirsiniz yöntemi çağırmak için benim sınıf basit bir sınıf fonksiyonu oluşturduk classname.methodnameve resimlerinizi ImageCaching.swiftsınıf kullanarak NSCache kaydedilir

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)
                                }
                            }
                        })

Mutlu Kodlama. Alkış :)


1

Swift 4.2 ve AlamofireImage

Bir kitaplık kullanmak sorun değilse, bunu kullanarak yapabilirsiniz AlamofireImage. benim örnekleri onun Github

Yer Tutucu Resimleri Örneği:

let imageView = UIImageView(frame: frame)
let url = URL(string: "https://httpbin.org/image/png")!
let placeholderImage = UIImage(named: "placeholder")!
imageView.af_setImage(withURL: url, placeholderImage: placeholderImage)

görüntülerle çalışmak için birçok kullanışlı işlev ve uzantıya sahiptir. önbelleklemeden ölçeklendirmeye ve yeniden boyutlandırmaya veya hatta görüntüye filtreler uygulamaya kadar. resimler uygulamanızda önemliyse, bu çerçeveyi kullanmanızı ve zaman kazanmanızı öneririm.


0

Ascyimageview kullanımı ile imageurl'u görüntü görüntüsüne kolayca yükleyebilirsiniz.

let image1Url: URL = URL (dize olarak "(imageurl)")! imageview.imageURL = image1Url


0

Sunucudan resim yükleme: -

func downloadImage(from url: URL , success:@escaping((_ image:UIImage)->()),failure:@escaping ((_ msg:String)->())){
    print("Download Started")
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else {
            failure("Image cant download from G+ or fb server")
            return
        }

        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        DispatchQueue.main.async() {
             if let _img = UIImage(data: data){
                  success(_img)
            }
        }
    }
}
func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

Kullanım: -

  if let url = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
                        self.downloadImage(from:url , success: { (image) in
                            print(image)

                        }, failure: { (failureReason) in
                            print(failureReason)
                        })
                    }

0

Hafif kütüphanede daha iyi performans UITableViewveya UICollectionViewkullanım için Smart Lazy Loading Url Asynchronous'dan görüntü yüklemek istiyorsanız bu tembel yükleme yaklaşımını kullanabilirsiniz

İçinde Smart 'Tembel Yükleme' UICollectionViewya UITableViewkullanılarak NSOperationve NSOperationQueueherhangi bir Görünüm (birden fazla resim yükleyebilirsiniz bu projede iOS So UICollectionViewveya UITableViewkullanarak bir uygulama performansını optimize ederek) Operationve OperationQueueeşzamanlılık için. Akıllı Tembel Yükleme: Görüntü indirme Servisi oluşturma. Hücrelerin görünürlüğüne göre indirmeye öncelik verin.

ImageDownloadService sınıfı, tek bir örnek oluşturur ve indirilen görüntüleri önbelleğe almak için NSCache örneğine sahiptir. Operasyon sınıfını, ihtiyacımıza göre işlevsellikten vazgeçmek için TOperation'a miras aldık. Operasyon alt sınıfının özelliklerinin işlevsellik açısından oldukça açık olduğunu düşünüyorum. KVO kullanarak durum değişikliklerini izliyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.