在Swift 3中,我试图从互联网上捕获图像,并拥有以下代码行:
var catPictureURL = NSURL(fileURLWithPath: "http://i.imgur.com/w5rkSIj.jpg")
var catPictureData = NSData(contentsOf: catPictureURL as URL) // nil
var catPicture = UIImage(data: catPictureData as! Data)
我在这里做错了什么?
答案 0 :(得分:47)
您的代码有一些原因:
我们要做的第一件事就是将您的变量声明为let
,因为我们以后不会修改它。
let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")! // We can force unwrap because we are 100% certain the constructor will not return nil in this case.
然后我们需要下载该URL的内容。我们可以使用URLSession
对象执行此操作。调用完成处理程序后,我们将从Web下载UIImage
。
// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)
// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
// The download has finished.
if let e = error {
print("Error downloading cat picture: \(e)")
} else {
// No errors found.
// It would be weird if we didn't have a response, so check for that too.
if let res = response as? HTTPURLResponse {
print("Downloaded cat picture with response code \(res.statusCode)")
if let imageData = data {
// Finally convert that Data into an image and do what you wish with it.
let image = UIImage(data: imageData)
// Do something with your image.
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
最后,您需要在下载任务上调用resume
,否则您的任务将永远无法启动:
downloadPicTask.resume()
。
所有这些代码起初可能看起来有点令人生畏,但URLSession
API是基于块的,因此它们可以异步工作 - 如果你阻止你的UI线程几秒钟,操作系统将终止你的应用程序。 / p>
您的完整代码应如下所示:
let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")!
// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)
// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
// The download has finished.
if let e = error {
print("Error downloading cat picture: \(e)")
} else {
// No errors found.
// It would be weird if we didn't have a response, so check for that too.
if let res = response as? HTTPURLResponse {
print("Downloaded cat picture with response code \(res.statusCode)")
if let imageData = data {
// Finally convert that Data into an image and do what you wish with it.
let image = UIImage(data: imageData)
// Do something with your image.
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
downloadPicTask.resume()
答案 1 :(得分:28)
let url = URL(string: "http://i.imgur.com/w5rkSIj.jpg")
let data = try? Data(contentsOf: url)
if let imageData = data {
let image = UIImage(data: imageData)
}
答案 2 :(得分:8)
使用此扩展程序并更快地下载图片。
extension UIImageView {
public func imageFromURL(urlString: String) {
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
activityIndicator.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
activityIndicator.startAnimating()
if self.image == nil{
self.addSubview(activityIndicator)
}
URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in
if error != nil {
print(error ?? "No Error")
return
}
DispatchQueue.main.async(execute: { () -> Void in
let image = UIImage(data: data!)
activityIndicator.removeFromSuperview()
self.image = image
})
}).resume()
}
}
答案 3 :(得分:7)
您还可以使用Alamofire \ AlmofireImage执行该任务: https://github.com/Alamofire/AlamofireImage
代码看起来应该是这样的(基于上面链接的第一个例子):
import AlamofireImage
Alamofire.request("http://i.imgur.com/w5rkSIj.jpg").responseImage { response in
if let catPicture = response.result.value {
print("image downloaded: \(image)")
}
}
虽然它很安全但你应该考虑是否值得开销。 如果您打算使用更多图像并想添加过滤器和转换,我会考虑使用AlamofireImage
答案 4 :(得分:5)
通过扩展
扩展原生功能的良好解决方案import Foundation
import UIKit
extension UIImage {
convenience init?(url: URL?) {
guard let url = url else { return nil }
do {
let data = try Data(contentsOf: url)
self.init(data: data)
} catch {
print("Cannot load image from url: \(url) with error: \(error)")
return nil
}
}
}
便利初始化程序可以使用并接受可选的URL
- 方法是安全的。
imageView.image = UIImage(url: URL(string: "some_url.png"))
答案 5 :(得分:4)
在 Swift 3:
上使用Alamofire为我服务第1步:
使用pod进行整合。
pod' Alamofire','〜> 4.4'
pod' AlamofireImage','〜> 3.3'
第2步:
导入AlamofireImage
导入Alamofire
第3步:
Alamofire.request("https://httpbin.org/image/png").responseImage { response in
if let image = response.result.value {
print("image downloaded: \(image)")
self.myImageview.image = image
}
}
答案 6 :(得分:2)
根据我的最简单方法是使用SDWebImage
将其添加到您的pod文件
pod 'SDWebImage', '~> 4.0'
运行pod install
现在导入SDWebImage
import SDWebImage
现在从网址设置图片
imageView.sd_setImage(with: URL(string: "http://www.domain/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
它将显示占位符图像,但是当下载图像时,它将显示来自网址的图像。您的应用程序永远不会崩溃
这是SDWebImage的主要功能
UIImageView,UIButton,MKAnnotationView的类别添加Web图像和缓存管理
异步图片下载
具有自动缓存到期处理的异步内存+磁盘映像缓存
背景图片解压缩
保证不会多次下载相同的网址
保证不会一次又一次地重试虚假网址
保证主线程永远不会被阻止 表演!
使用GCD和ARC
答案 7 :(得分:1)
使用UIImageView扩展名加载URL图像。
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func imageURLLoad(url: URL) {
DispatchQueue.global().async { [weak self] in
func setImage(image:UIImage?) {
DispatchQueue.main.async {
self?.image = image
}
}
let urlToString = url.absoluteString as NSString
if let cachedImage = imageCache.object(forKey: urlToString) {
setImage(image: cachedImage)
} else if let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
DispatchQueue.main.async {
imageCache.setObject(image, forKey: urlToString)
setImage(image: image)
}
}else {
setImage(image: nil)
}
}
}
}
答案 8 :(得分:0)
let url = ("https://firebasestorage.googleapis.com/v0/b/qualityaudit-678a4.appspot.com/o/profile_images%2FBFA28EDD-9E15-4CC3-9AF8-496B91E74A11.png?alt=media&token=b4518b07-2147-48e5-93fb-3de2b768412d")
self.myactivityindecator.startAnimating()
let urlString = url
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url)
{
(data, response, error) in
if error != nil {
print("Failed fetching image:", error!)
return
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
print("error")
return
}
DispatchQueue.main.async {
let image = UIImage(data: data!)
let myimageview = UIImageView(image: image)
print(myimageview)
self.imgdata.image = myimageview.image
self.myactivityindecator.stopanimating()
}
}.resume()
答案 9 :(得分:0)
我使用 AlamofireImage 它适用于 Loading url 在 ImageView 中,它也有 Placeholder 选项.
func setImage (){
let image = “https : //i.imgur.com/w5rkSIj.jpg”
if let url = URL (string: image)
{
//Placeholder Image which was in your Local(Assets)
let image = UIImage (named: “PlacehoderImageName”)
imageViewName.af_setImage (withURL: url, placeholderImage: image)
}
}
注意:- 不要忘记在 Pod 文件和导入语句中添加 AlamofireImage
举个例子,
pod 'AlamofireImage' 在你的 PodFile 和 ViewController import AlamofireImage