在Swift上从URL加载/下载图像

我想从我的应用程序中的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一起工作,我该如何解决这个问题。

690920 次浏览

你需要做的是:

UIImage(data: data)

在Swift中,他们已经用规则构造函数取代了大多数Objective C工厂方法。

看到的:

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

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)

唯一缺少的是一件东西!

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 4更新) 为了直接回答最初的问题,下面是发布的Objective-C代码片段的快速等效版本

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

免责声明:

值得注意的是,Data(contentsOf:)方法将在执行代码的同一线程中下载url 同步的内容,因此将在应用程序的主线程中调用此方法。

让相同的代码异步运行,而不阻塞UI的简单方法是使用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!)
}
}

也就是说,在现实生活中的应用程序中,如果您希望获得最佳的用户体验并避免同一映像的多次下载,您可能还希望不仅下载它们,而且缓存它们。已经有相当多的库可以无缝地做到这一点,而且它们都非常易于使用。我个人推荐翠鸟:

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)

就是这样

Xcode 8或更高版本•Swift 3或更高版本

同步:

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

异步:

创建一个带有完成处理程序的方法,从您的url获取图像数据

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

创建一个方法来下载映像(启动任务)

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")
// always update the UI from the main thread
DispatchQueue.main.async() { [weak self] in
self?.imageView.image = UIImage(data: data)
}
}
}

用法:

override func viewDidLoad() {
super.viewDidLoad()
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.")
}

扩展:

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

用法:

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

我把这个问题的最佳答案的代码包装成一个单一的,可重用的类扩展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")

如果你只是想加载image (异步!) -只需添加这个小扩展到你的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)
}
}
}
}
}

然后这样用:

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

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

一种获取图像的方法是安全的,适用于Swift 2.0和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)
}

然后你可以像这样调用这个方法:

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

如果你要用图像更新视图,你必须在" 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
}

如果您在UI中使用映像,则需要最后一部分,因为网络调用需要时间。如果您尝试使用图像而不像上面那样调用dispatch_async来更新UI,计算机将在图像仍然被提取时寻找图像,发现没有图像(还没有),然后继续前进,就好像没有找到图像一样。把你的代码放在dispatch_async完成闭包中,告诉计算机:“去获取这个图像,当你完成时,然后完成这段代码。”这样,当调用代码时,您就有了图像,事情就会正常工作。

Swift 2.0:

1)

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

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

2)将此方法添加到VC或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)
}
}
}

用法:

self.load_image(" url strig here")

__abc0 || __abc1

我得到惊人的结果!!使用AlamofireImage swift库

它提供了多种功能,如:

  • < em >异步下载< / em >
  • 自动清除图像缓存,如果内存警告发生的应用程序
  • 图像URL缓存
  • 图像缓存
  • 避免重复下载

在你的应用中很容易实现

步骤1安装吊舱


Alamofire 3.3.x

豆荚的Alamofire

AlamofireImage 2.4.x

豆荚的AlamofireImage

步骤2导入并使用

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)

就是这样! !它会照顾好一切


非常感谢< >强Alamofire人< / >强,让iDevelopers的生活变得简单;)

在Swift中使用此代码

imageView.image=UIImage(data: NSData(contentsOfURL: NSURL(string: "http://myURL/ios8.png")!)!

斯威夫特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


}

一个快速的黑客,如果你想快速检查图像从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)来下载image

用法:

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

__abc0•__abc1

Leo Dabus的答案非常棒!我只是想提供一个一体化的功能解决方案:

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

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

斯威夫特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
}

对于Swift-3及以上版本:

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

斯威夫特4:一个简单的小图像加载器(例如:缩略图),使用NSCache并且总是运行在主线程上:

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


}

用法:

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

翠鸟是一个最好的库加载图像到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)

使用Ascyimageview,你可以很容易地加载imageurl在imageview。

let image1Url:URL = URL(字符串:"(imageurl)" as string)! imageview。imageURL = image1Url

这是从URL加载/下载图像的工作代码。NSCache自动和显示占位符图像下载和加载实际图像(Swift 4 | Swift 5代码)。

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

像这样使用:

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

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

编辑为最新更改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()
}
}

<强>幸福的鳕鱼。欢呼:)< / >强

斯威夫特4::

这将在加载图像时显示加载器。 你可以使用NSCache来临时存储图像

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

用法:-

truckImageView.loadImageUsingCache(withUrl: currentTruck.logoString)

我建议使用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()
}
})

你可以使用pod SDWebImage来实现同样的功能。它很容易使用。你可以在这里获得documentaion 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)
}
})

从服务器加载图像:-

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

用法:-

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

Swift 4.2和AlamofireImage

如果使用库不是问题,你可以通过AlamofireImage的帮助来完成。 我的样本是从它的Github

占位符图片

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)

它有许多方便的功能和扩展工作与图像。从缓存到缩放和调整大小,甚至在图像上应用过滤器。如果图像在你的应用中很重要,我建议使用这个框架来节省你的时间。

斯威夫特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
}
}
}
}
}
}

使用

override func awakeFromNib() {
super.awakeFromNib()
if let url = URL(string:"<imageURLHere>"){
imgView.load(url: url)
}
}

为了在UITableViewUICollectionView中获得更好的性能,使用轻量级库智能延迟加载。如果你想从url异步加载图像,可以使用这种惰性加载方法

所以在这个项目中,我们可以通过使用OperationOperationQueue的并发性来优化应用程序的性能,在任何视图(UICollectionViewUITableView)中下载多个图像。以下是这个项目的重点智能延迟加载:创建图像下载服务。根据单元格的可见性优先下载。

ImageDownloadService类将创建一个单例实例,并有NSCache实例来缓存已下载的图像。我们已经将Operation类继承给TOperation,以便根据我们的需要修改功能。我认为就功能而言,operation子类的属性非常清楚。我们使用KVO监测操作状态的变化。

在使用SwiftUI时,SDWebImageSwiftUI是最好的选择。

通过XCode的Swift Package Manager: https://github.com/SDWebImage/SDWebImageSwiftUI.git添加依赖项

然后使用WebImage()而不是Image()

WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
class ImageStore: NSObject {
static let imageCache = NSCache<NSString, UIImage>()
}


extension UIImageView {
func url(_ url: String?) {
DispatchQueue.global().async { [weak self] in
guard let stringURL = url, let url = URL(string: stringURL) else {
return
}
func setImage(image:UIImage?) {
DispatchQueue.main.async {
self?.image = image
}
}
let urlToString = url.absoluteString as NSString
if let cachedImage = ImageStore.imageCache.object(forKey: urlToString) {
setImage(image: cachedImage)
} else if let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
DispatchQueue.main.async {
ImageStore.imageCache.setObject(image, forKey: urlToString)
setImage(image: image)
}
}else {
setImage(image: nil)
}
}
}
}

用法:

let imageView = UIImageView()
imageView.url("image url")

AsyncImage 在iOS 15之后正式引入,它是一个同步加载和显示图像的视图。

 var imageView : AsyncImage


imageView = AsyncImage(url: URL(string: entry.photo))
.frame(width: 200, height: 200)

它还支持:

详见医生

你可以用翠鸟从image url下载图像。

首先导入翠鸟 as-

pod 'Kingfisher'

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

import Kingfisher

之后添加一个临时的UIImageView

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


if let finalImage = imgView.image {
// finalImage is your 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

这里有一个详细的博客帖子关于它。

class Downloader {
    

class func downloadImageWithURL(url: String) -> UIImage! {
        

let date = NSData(contentsOf: URL(string: url)!)
return UIImage(data: date! as Data)
}
}

用法:

let img = Downloader.downloadImageWithURL(url: imageURL)
self.imageView1.image = img

干净的方式:

extension URL {
var favIcon16: UIImage? { getFav(ofSize: .s) }
var favIcon32: UIImage? { getFav(ofSize: .m) }
var favIcon64: UIImage? { getFav(ofSize: .l) }
var favIcon128: UIImage? { getFav(ofSize: .xl) }
var favIcon256: UIImage? { getFav(ofSize: .xxl) }
var favIcon512: UIImage? { getFav(ofSize: .xxxl) }


private func getFav(ofSize s: FavSize) -> UIImage? {
guard UIApplication.shared.canOpenURL(self),
let favUrl = URL(string: "https://www.google.com/s2/favicons?sz=\(s.rawValue)&domain=\(self.absoluteURL)"),
let data = try? Data(contentsOf: favUrl)
else { return nil }
return UIImage(data: data)
}
private enum FavSize: Int, CaseIterable { case s = 16, m = 32, l = 64, xl = 128, xxl = 256, xxxl = 512 }
}

和用法:

let myUrl = URL(string: "http://facebook.com")
myImgView.image = myUrl.favIcon16