我想从我的应用程序中的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 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")
}
}
}
}
与扩展
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")
}
}
}
}
扩展使用
myImageView. setCustomImage("url")
具有缓存支持
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()
}
}
}
Swift 4.1我创建了一个函数,只是传递图像url,图像生成后缓存键设置为完成块。
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()
})
}
}
}
一个快速的黑客,如果你想快速检查图像从url
let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")
let imagedData = NSData(contentsOfURL: imageURL!)!
imageView?.image = UIImage(data: imagedData)
我在一个tableview中实现了一个只有图像的自定义单元格
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
}
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")