In Swift 3, I am trying to capture an image from the internet, and have these lines of code:
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)
What am I doing wrong here?
This question is related to
swift3
The easiest way according to me will be using SDWebImage
Add this to your pod file
pod 'SDWebImage', '~> 4.0'
Run pod install
Now import SDWebImage
import SDWebImage
Now for setting image from url
imageView.sd_setImage(with: URL(string: "http://www.domain/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
It will show placeholder image but when image is downloaded it will show the image from url .Your app will never crash
This are the main feature of SDWebImage
Categories for UIImageView, UIButton, MKAnnotationView adding web image and cache management
An asynchronous image downloader
An asynchronous memory + disk image caching with automatic cache expiration handling
A background image decompression
A guarantee that the same URL won't be downloaded several times
A guarantee that bogus URLs won't be retried again and again
A guarantee that main thread will never be blocked Performances!
Use GCD and ARC
To know more https://github.com/rs/SDWebImage
Using Alamofire worked out for me on Swift 3:
Step 1:
Integrate using pods.
pod 'Alamofire', '~> 4.4'
pod 'AlamofireImage', '~> 3.3'
Step 2:
import AlamofireImage
import Alamofire
Step 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
}
}
I use AlamofireImage it works fine for me for Loading url within ImageView, which also has Placeholder option.
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)
}
}
Note:- Dont forget to Add AlamofireImage in your Pod file as well as in Import Statment
Say Example,
pod 'AlamofireImage' within Your PodFile and in ViewController import AlamofireImage
Good solution to extend native functionality by extensions
import UIKit
extension UIImage {
convenience init?(url: URL?) {
guard let url = url else { return nil }
do {
self.init(data: try Data(contentsOf: url))
} catch {
print("Cannot load image from url: \(url) with error: \(error)")
return nil
}
}
}
Convenience initializer is failable and accepts optional URL
– approach is safe.
imageView.image = UIImage(url: URL(string: "some_url.png"))
Use extension for UIImageView to Load URL Images.
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)
}
}
}
}
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)
}
You could also use Alamofire\AlmofireImage for that task: https://github.com/Alamofire/AlamofireImage
The code should look something like that (Based on the first example on link above):
import AlamofireImage
Alamofire.request("http://i.imgur.com/w5rkSIj.jpg").responseImage { response in
if let catPicture = response.result.value {
print("image downloaded: \(image)")
}
}
While it is neat yet safe, you should consider if that worth the Pod overhead. If you are going to use more images and would like to add also filter and transiations I would consider using AlamofireImage
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()
Use this extension and download image faster.
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()
}
}
Source: Stackoverflow.com