i've been working on an app that loads a lot of images. I have a table view cell that each of them has an image.
Images are stored in S3 bucket.
Each image is pretty big, around 720 KB, and each time i scroll the screen freezes a bit to get the whole image.
Here's my code that gets image
let url: String = "\(K.baseURLForImage)\(cellImageURL)"
let validURL = URL(string: url)
if let imageData = try? Data(contentsOf: validURL!) {
let image = UIImage(data: imageData)
cell.cellImage.image = image
}
Certainly it is not nice, so is there any way I can get around with this?
I've heard that not using dequeueReusableCell
is not good
Thank you in advance.
EDIT
I added these lines
if let validURL = URL(string: url) {
task = URLSession.shared.dataTaskPublisher(for: validURL)
.sink(receiveCompletion: { completion in
// error handling
print("failed URL: '\(url)'")
}, receiveValue: { (data, response) in
image = UIImage(data: data)
})
return image
} else {
return nil
}
But I got nil
every time I call this function.
I checked that the URL of image is valid.
CodePudding user response:
As commented above, Data(contentsOf:)
is a blocking call and any activity on the thread on which this is called will be stopped, including if this is called from the main thread.
Switch to using one of the URLSession
functions.
One possible example:
import Combine
let url = "https://via.placeholder.com/150"
var task: AnyCancellable? // Do not let this go out of scope until data is loaded
if let validURL = URL(string: url) {
task = URLSession.shared.dataTaskPublisher(for: validURL)
.sink(receiveCompletion: { completion in
// error handling
}, receiveValue: { (data, response) in
let image = UIImage(data: data)
cell.cellImage.image = image
})
}
CodePudding user response:
I solved my problem with Kingfisher!
Here's my code
import Kingfisher
let url: String = "some url"
let validURL = URL(string: url)
KF.url(validURL!)
.set(to: cell.cellImage)
return cell