我想从我的应用程序中的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一起工作,我该如何解决这个问题。
您可以使用pod SDWebImage来实现相同的功能。它很容易使用。你可以在SDWebImage这里获得文档
下面是示例代码
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)
}
})
Swift 2带有错误句柄和自定义请求头
简单地添加扩展到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()
}
}
}
然后,使用新的imageFromUrl(urlString: String)下载图像
用法:
imageView.imageFromUrl("https://i.imgur.com/ONaprQV.png")
编辑为最新更改2021年9月
// It's better to use extension
extension UIImageView {
func downloadImage(from URLString: String, with completion: @escaping (_ response: (status: Bool, image: UIImage? ) ) -> Void) {
guard let url = URL(string: URLString) else {
completion((status: false, image: nil))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
guard error == nil else {
completion((status: false, image: nil))
return
}
guard let httpURLResponse = response as? HTTPURLResponse,
httpURLResponse.statusCode == 200,
let data = data else {
completion((status: false, image: nil))
return
}
let image = UIImage(data: data)
completion((status: true, image: image))
}.resume()
}
}
快乐的鳕鱼。欢呼:)
我把这个问题的最佳答案的代码包装成一个单一的,可重用的类扩展UIImageView,所以你可以直接在你的故事板中使用异步加载UIImageViews(或从代码中创建它们)。
这是我的班级:
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!)
}
}
}
}
下面是如何使用它:
imageView.downloadImage("http://www.image-server.com/myImage.jpg")
斯威夫特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
}