我想从我的应用程序中的URL加载图像,所以我首先尝试了Objective-C和它的工作,但是,与Swift,我有一个编译错误:

'imageWithData'不可用:使用对象构造'UIImage(data:)'

我的函数:

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

在objective - 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";
 }

有人能解释一下为什么imageWithData:不能与Swift一起工作,我该如何解决这个问题。


当前回答

供你参考:对于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!)
            }
        }
    }
}

其他回答

我建议使用Kingfisher库来异步下载图像。使用翠鸟最好的部分是,它默认缓存所有下载的图像,图像url作为id。下次当您请求下载具有特定URl的图像时,它将从缓存中加载它。

用法:

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

你可以很容易地下载图像从图像url翠鸟。

首先进口翠鸟as-

pod 'Kingfisher'

然后在类中以-的形式导入它

import Kingfisher

之后添加一个临时的UIImageView

let imgView = UIImageView()
imgView.kf.setImage(with: yourImageURL)

if let finalImage = imgView.image {
    // finalImage is your image
}

斯威夫特4

这个方法将从一个网站异步下载图像并缓存它:

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

在使用:

    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
    }

斯威夫特2。x答案下载图像到文件(与Leo Dabus的答案相反,它将图像存储在内存中)。根据Leo Dabus的回答和Rob的回答,从完成处理程序的NSURLSession DownloadTaskWithRequest中获取数据:

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

}

这是最简单的方法,你不必担心async,或者它是如何工作的。

import SDWebImage

imageView.sd_setImage(with: URL(string: ".net/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
Using UIImageView+WebCache category with UI

这里有一篇关于它的详细博文。