Image loading taking more time in swift - swift

I am working on an application, where I am loading some images from the server and showing it on table view using Alamofire. But the problem is it is taking so much time to load the image. I want to show the image, like a blurry image until the time image is not loading. Please, someone, help me.
cell.profileImageView?.pin_setImage(from: URL(string: modelArray[indexPath.row]))

This one is the solution using Kingfisher pod. You can set an activity Indicator while image is loaded.
let imageUrl = modelArray[indexPath.row]
//set activity indicator until image is loaded
cell.profileImageView?.kf.indicatorType = .activity
if let url = URL(string: imageUrl) {
let resource = ImageResource(downloadURL: url)
cell.profileImageView?.kf.setImage(with: resource)
}

Related

How to display image from known image path - SwiftUI

I've got an array of image URLs (all from storage, not internet). How can I show the images themselves?
Simplified code:
#Binding var files:[URL]//Array of image URLs taken from an NSOpenPanel instance
Form{
if files.count>0{
Image(files[0].path)//Problem
}
}
You say NSOpenPanel, so I'm making going to make the assumption here that we don't need to worry about waiting to load the image over a network:
if let nsImage = NSImage(contentsOf: url) {
Image(nsImage: nsImage)
}

Kingfisher KFImage how to make it load the cache even if the URL changed?

What I want to achieve
I want the KFImage to always read from memory and disk cache, not redownloading the image every time. The user will have a smooth experience without seeing the image downloading for a few seconds everytime the view loads.
What is wrong
The KFImage view load its images from the profileImages variable, which is initialized as empty list. That list does not get populated with URLs until getProfileImage() called which takes a few seconds.
Even though the image URL is the same, there would be a few seconds of gap right after the view appears, so KFImage will not load from its cache, and need to redownload images. Is it possible to make the KFImage view always load from cache even if URL change? Or is there another solution to my problem?
import KingfisherSwiftUI
struct ProfileSubview: View {
#State var profileImages: [URL] = []
var body: some View {
ForEach(0..<profileImages.count, id: \.self){index in
KFImage(profileImages[index])
}
}
.onAppear{
getProfileImage()
}
}
func getProfileImage(){
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let storage = Storage.storage().reference().child("User_Profile")
storage.downloadURL{url, error in
if let error = error{
print("Error downloading image, \(error)")
}
profileImages.append(url!)
}
}

UIImage not loading from AWS S3 url

I'm trying to download an image from a URL but the image doesn't load.
I ported this class from objective-C to swift and this specific part of the code stopped working.
My URL looks like this. Can anybody tell me what am I doing wrong?
https://mydomain-files.s3.amazonaws.com/files/log/773/IMG_20200408_125029.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=mycredentials%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20200413T171303Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=mysignature
cell.previewImageView.sd_setImage(with: url, placeholderImage: UIImage(named: "nodata"), completed: { image, error, cacheType, imageURL in
if image != nil {
cell.previewImageView.image = image
}
})
I have tried using just https://mydomain-files.s3.amazonaws.com/files/log/773/IMG_20200408_125029.jpg this part and it doesn't work either. The image loads fine in Volley for Android and inside the browser.
Error
Error Domain=SDWebImageErrorDomain Code=1001 "Downloaded image has 0 pixels" UserInfo={NSLocalizedDescription=Downloaded image has 0 pixels})
Edit 2:
I have tried adding addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) to the url, it just doesn't work
Obviously, since the image does not load it means that image is nil.
I would advise you to convert your code to the one below and handle errors appropriately:
cell.previewImageView.sd_setImage(with: url, placeholderImage: UIImage(named: "nodata"), completed: { image, error, cacheType, imageURL in
if let error = error {
// Handle errors here
// It may be as simple as forgetting to whitelist S3 url in Info.plist
}
else if image != nil {
cell.previewImageView.image = image
}
})
If there are no errors, check the contents of other variables – they might give you a clue as to what's going wrong.

Asynchronous loading image with request

I have an api in which I get a link for request. In order to get a picture, I need to make a request in response to which I receive image data. How can I make getting asynchronous images? I find a lot of libraries and videos in youtube where this make with image link. But how i can do it in my case?
let token_type = KeychainWrapper.standard.string(forKey: "token_type")
let access_token = KeychainWrapper.standard.string(forKey: "access_token")
let headers:HTTPHeaders? = ["Authorization": "\(token_type ?? "") \(access_token ?? "")"]
Alamofire.request(cellInfo.imageLink ?? "", method: .get, headers: headers).responseImage { response in
if let image = response.result.value {
cell.firstTypeImageView.image = image
}
}
The issue with your example is that if the cell is reused by the time the image is retrieved, you’ll be updating the wrong row with this image. If updating the image view, it’s better to use the UIImageView extension. You enjoy several benefits with table view cells when you do this because it will automatically cancel the prior request for this cell. This means that:
It eliminates the problem of scrolling quickly having the image view in a reused cell flickering as images are retrieved for rows in the table.
It also means that you don’t have to worry about the current cell getting backlogged behind requests for cells that are no longer visible.
So, you might do something like:
if let imageLink = cellInfo.imageLink, let url = URL(string: imageLink) {
var request = URLRequest(url: url)
let authValue = "\(token_type ?? "") \(access_token ?? "")"
request.setValue(authValue, forHTTPHeaderField: "Authorization")
cell.firstTypeImageView.af_setImage(withURLRequest: request)
}
Or maybe you have a placeholder image, e.g. blank.png, then you’d do:
cell.firstTypeImageView.af_setImage(withURLRequest: request, placeholderImage: UIImage(named: "blank"))
Note, if your images are much larger than the image view in which you’re presenting them, you can see some stuttering in the tableview as the OS struggles to deal with such large assets. In that scenario, you can add a resizing filter:
let filter = AspectScaledToFillSizeFilter(size: cell.firstTypeImageView.frame.size) // or use whatever size appropriate
cell.firstTypeImageView.af_setImage(withURLRequest: request, placeholderImage: UIImage(named: "blank"), filter: filter)

How to display local JPG image in a PFImageView

I have several PFImageViews that are there to show images downloaded from Parse. However, there is one local image that I want to be able to load when I desire. For some reason, this code isn't working. Any help is greatly appreciated, thanks!
In cellForRowAtIndexPath:
let checkInImage = UIImage(named: "checkin.jpg")!
let checkInFile = UIImageJPEGRepresentation(checkInImage, 1.0)!
let imagePFFile = PFFile(data: checkInFile)!
tableViewCell.PFImageViewOne.file = imagePFFile
tableViewCell.PFImageViewOne.loadInBackground()
Since PFImageView is a subclass of UIImageView, you should be able to just set the image view's image property to your image like this:
tableViewCell.PFImageViewOne.image = checkInImage