How to show SDWebimage for background Colour in Swift - ios

SDWebImage is great library for conversion URL to image. Its working great. But, I have following issue
// For imageview, we are setting like
eventImageView.sd_setImage(with: URL(string: imageUrl), placeholderImage: UIImage(named: "placeholder.png"))
// but, for Image as UIColor,
Showing compiler error if I use like following
self.scrollView.backgroundColor = UIColor(patternImage: sd_setImage(with: URL(string: imageUrl), placeholderImage:UIImage(named: "placeholder.png")))
even I tried like following
let imageBG = sd_setImage(with: URL(string: image), placeholderImage: UIImage(named: "placeholder.png"))
self.scrollView.backgroundColor = UIColor(patternImage: imageBG)
and its showing following error
Use of unresolved identifier 'sd_setImage'
Can anyone suggest me for how to fix this?

You need to use SDWebImageManager to download image at first and then use it in UIColor(patterImage:) constructor.
Try code below:
SDWebImageManager.shared().loadImage(with: URL(string: imageUrl), options: [], progress: nil, completed: { (image, data, error, cacheType, success, url) in
DispatchQueue.main.async {
guard let image = image else {
return
}
self.scrollView.backgroundColor = UIColor(patternImage: image)
}
})

That's happens because sd_setImage a UIImageView method (eventImageView should be a UIImageView), the init(patternImage:) declaration is:
init(patternImage image: UIImage)
which means that patternImage parameter is a UIImage not UIImageView.
To solve this, you should first load the image view, once the loading has done you could assign the color to be the image of the image view:
eventImageView.sd_setImage(with: URL(string: imageUrl), placeholderImage: UIImage(named: "placeholder.png")) { (image, error, cache, url) in
self.scrollView.backgroundColor = UIColor(patternImage: image)
}
Or (without the placeholder):
eventImageView.sd_setImage(with: URL(string: imageUrl)) { (image, error, cache, url) in
self.scrollView.backgroundColor = UIColor(patternImage: image)
}

sd_setImage(with is applicable to UIImageView
Create struct as -
struct ImageSetter {
static func setImage(scrollView: UIScrollView,myImageView: UIImageView,imageUrl: URL,placeHolderImage: UIImage){
myImageView.sd_setImage(with: imageUrl, placeholderImage: placeHolderImage, options: [], completed: { (imageBackground, error, cache, url) in
scrollView.backgroundColor = UIColor.init(patternImage: imageBackground ?? UIImage(named: "place-holder-image")!)
})
}
}
Use -
ImageSetter.setImage(scrollView: scrollView, myImageView: testImageView, imageUrl: url, placeHolderImage: image)
SDWebImage

Related

how to do something right after downloading image using SDWebImage?

So, I want to show a message to the user right after an image is downloaded and set in ImageView. I am using SDWebImage. how to do that?
Here is my current code
profilePictureImageView.sd_setImage(with: referenceImage, placeholderImage: UIImage(named: ImageName.defaultProfilePicture))
You can do it like this
profilePictureImageView.sd_setImage(with: referenceImage, placeholderImage: UIImage(named: "cod_logo"), options: [.highPriority]) { (image, error, cashtype, url) in
if image != nil{
// Do something Here after load image
}
print(error) // Your error is here
}
This is pod 'SDWebImage' = '4.0.0' and XCode == 11.3.1
self.userAvatar.sd_setImage(with: URL(string: __user_avatar), placeholderImage: UIImage(named: "UserDefalutAvatar"), options: .progressiveDownload, progress: { (receivedSize, expectedSize, targetURL) in
print("The progress value for the downloading is \(receivedSize)")
}) { (downloadedImage, downloadedError, imageCacheType, downloadedURL) in
if let _downloadedError = downloadedError {
print("Download image encountered error. \(_downloadedError.localizedDescription)")
return
}
if let _downloadedImage = downloadedImage {
print("This is downloaded image, you can do it what you want")
}
}

Setting an image to an imageCache to the beginning of the imageCache and not the end

I set an object to the imageCache with this:
self.picPostPicImageCache.setObject(UIImage(data:imageData)!,forKey: urlString as NSString)
}
This is used in a tableview like so:
let cell : ImagePostTableViewCell = BarSelectedTableView.dequeueReusableCell(withIdentifier: "ImagePostTableViewCell", for: indexPath) as! ImagePostTableViewCell
if let PicPostCacheImage = picPostPicImageCache.object(forKey: picPostPicUrlArray[indexPath.row] as NSString) { if let PicProPicCacheImage = picPostProPicImageCache.object(forKey: picPostProPicUrlArray[indexPath.row] as NSString) {
cell.userImagePostView.image = PicPostCacheImage
cell.userImageView.image = PicProPicCacheImage
}
} else {
cell.userImagePostView.sd_setImage(with: URL(string: picPostPicUrlArray[indexPath.row] as String), placeholderImage: UIImage(named: "defaultPropic"), options: [.continueInBackground, .progressiveLoad])
cell.userImageView.sd_setImage(with: URL(string: picPostProPicUrlArray[indexPath.row] as String), placeholderImage: UIImage(named: "defaultPropic"), options: [.continueInBackground, .progressiveLoad])
}
The problem I run into is when I want to add a new photo to the cache. Currently, I use the same method of adding a new photo like this.
self.picPostPicImageCache.setObject(UIImage(data:imageData)!,forKey: urlString as NSString)// new photo
However, this adds it to the end of the cache and displays the image at the bottom of tableview as opposed to the top. I would like to add it to the beginning of the cache. Is there any possible way of doing this without deleting the elements in the cache and reloading?

xCode error:- Cannot assign value of type 'URL?' to type 'UIImage?'

I am attempting to pull an image url from Firebase Users profile.
When I call:-
#IBOutlet weak var profileImage: UIImageView?
profileImage?.image = Auth.auth().currentUser?.photoURL
I get the following error appear:-
Cannot assign value of type 'URL?' to type 'UIImage?'
I try to use the fixes that xcode provides but these only lead to further issues.
When I print:-
print(Auth.auth().currentUser?.photoURL as Any)
I get the following output, so I know there is an image there.
Optional(https://graph.facebook.com/10X60X70X35X101X5/picture)
How am I able to pull this image in, or is it possible to convert it to a string so I am able to use it?
Thanks in advance.
You can't assign url to image , use SDWebImage to download it asynchronously to not block main thread
if let url = Auth.auth().currentUser?.photoURL {
self.profImageV.sd_setImage(with: url , placeholderImage: UIImage(named: "edit2.png"))
}
The error message is very clear, you're trying to assign a URL? type to UIImage? type. Since it's a URL? you should first unwrap it, and download the image with this url. When you have your UIimage then you can assign it.
Actually you are converting URL type to UIImage type, that is not possible. You need to download image from url and set in an image view or wherever you want to use.
DispatchQueue.global(qos: .background).async {
if let url = URL(string: <#imageUrl#>) {
do {
let imgData = try Data(contentsOf: url)
if let image = UIImage(data: imgData) {
DispatchQueue.main.async {
self.imageView.image = image
}
}
} catch {
debugPrint("From catch block: Image could not be downloaded !!")
}
}
}
You need to download the image and then set the imageView's image to the downloaded image. You can do this using URLSession's dataTask:
// Playground code
import UIKit
import PlaygroundSupport
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
let session = URLSession.shared
let url = URL(string: "http://via.placeholder.com/400x400")!
_ = session.dataTask(with: url) { data, response, error in
guard error == nil else {
print(error)
return
}
guard let data = data else {
print("[DEBUG] - No data returned")
return
}
DispatchQueue.main.async {
imageView.image = UIImage(data: data)
}
}.resume()
PlaygroundPage.current.liveView = imageView
Or you can use a library such as KingFisher to handle it for you, then you just call it like so:
let url = URL(string: "url_of_your_image")
imageView.kf.setImage(with: url)

Image View Does not display image after setting image to it downloaded from url

here it is what i am doing.
extension UIImageView {
func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .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() {
self.image = image
}
}.resume()
}
func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
guard let url = URL(string: link) else { return }
downloadedFrom(url: url, contentMode: mode)
}
i checked it in image its show image in preview in debug state. but after self.image = image
nothing change on image view image is not displaying. anyone know where the problem is ? thanks
Most efficient way for downloading image: SDWebImage
You can use a Cocoa Pod file for SDWebImage Library.
init the pod file.
pod 'SDWebImage'
install Pod file.
Swift snippet:
import SDWebImage
imageView.sd_setImage(with: URL(string: #"user-url"), placeholderImage: UIImage(named: "placeholder"))
Objective-C Snippet:
#import <SDWebImage/UIImageView+WebCache.h>
...
[imageView sd_setImageWithURL:[NSURL URLWithString:#"user-url"]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
Hope this will help to do efficient way to downloading images basically, whenever you are using UICollectionView or UITableView.
You can do it easier with Kingfisher library like below.
let url = URL(string: "url_of_your_image")
imageView.kf.setImage(with: url)
Try this below code
if data != nil { // check nil here
let image = UIImage(data: data)
DispatchQueue.main.async {
self.image = image
}
}
}.resume()
no need to check the image mime type, just a check of data and image is sufficient, since data will be nil for error and vice versa.
change as
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, let image = UIImage(data: data) else { return }
DispatchQueue.main.async {
self.image = image
}
}.resume()
And cross check with image with debugger.

Using SdWebImage and Image Change immediately by swift

This is Question Video
I have a problem about imageView by using SDWebImage.
I change user's image and already get new user's image url, but when I push to this ViewController, it will show the old image first and change to new image.
What's wrong with me?
Thanks.
var avatar:String = "" // previous VC data pass to here
var photoImageView:UIImageView = { () -> UIImageView in
let ui = GeneratorImageView()
ui.backgroundColor = UIColor.clear
ui.layer.masksToBounds = true
ui.contentMode = .scaleAspectFill
return ui
}()
override func viewDidLoad() {
super.viewDidLoad()
iconImageFromUrl(imageView: iconImageView, url: avatar, isResize: false)
}
func iconImageFromUrl(imageView:UIImageView, url:String,isResize:Bool) {
imageView.setShowActivityIndicator(true)
imageView.setIndicatorStyle(.gray)
imageView.sd_setImage(with: URL(string:url), placeholderImage: nil, options: .lowPriority, progress: nil
, completed: { (image, error, cacheType, url) in
guard image != nil else{
imageView.image = resizeImage(image: #imageLiteral(resourceName: "defaultIcon"), newWidth: 50)
return
}
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
if data != nil
{
if let image = UIImage(data: data!)
{
DispatchQueue.main.async {
if isResize == true{
imageView.image = resizeImage(image: image, newWidth: 250)
}else{
imageView.image = image
}
}
}
}
}
})
}
sd_setImage method is written inside a category of UIImageView. After downloading the image it sets the image on UIImageview on its own and in the completion closure returns the downloaded/cached UIImage as well.
You dont need to create Data from imageUrl and set it again. If you want to resize image, you can do it on the returned image.
Also, you dont need to check the image nil for setting the default image, just pass the resized default image as placeholder image
imageView.sd_setImage(with: URL(string:url), placeholderImage: resizeImage(image: #imageLiteral(resourceName: "defaultIcon"), newWidth: 50), options: .lowPriority, progress: nil
, completed: { (image, error, cacheType, url) in
guard image != nil else {
return
}
if isResize {
imageView.image = resizeImage(image: image, newWidth: 250)
} })

Resources