Reputation: 85
Currently I have a collection view of thumbnail images, Upon pressing that thumbnail image cell then it should call a function that would retrieve the Image data via API and shows the full image via the hidden ImageView.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dataManager.downloadAttachment(id: attachments[indexPath.row].attachmentID)
if dataManager.dataHolder != nil {
attachmentImage.image = UIImage.init(data: dataManager.dataHolder!)
attachmentImage.isHidden = false
}
print(attachments[indexPath.row].attachmentID)
}
and
func downloadAttachment(id:Int) {
let finalUrl = "\(urlAttachment)\(id)/data"
if let url = URL(string: finalUrl){
var request = URLRequest(url: url)
request.setValue(apiKey, forHTTPHeaderField: header)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
print("Attachment Downloaded")
self.dataHolder = data
}
task.resume()
}
}
The obvious issue with this is that the image wouldn't show on the first attempt since it would still be retrieving the image and the dataHolder would still be nil, But if I tap on the cell twice then the image will be shown correctly.
Is there a simple way to maybe just tap once and make it shows a place holder until finished downloading and update the place holder with an actual image accordingly? Or any other proper way to handle this?
Upvotes: 1
Views: 163
Reputation: 141
You can use closures to achieve what you asked for. The updated code looks like this.
func downloadAttachment(id:Int,completionHandler completion: @escaping ((Data)->Void)) {
let finalUrl = "\(urlAttachment)\(id)/data"
if let url = URL(string: finalUrl){
var request = URLRequest(url: url)
request.setValue(apiKey, forHTTPHeaderField: header)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
print("Attachment Downloaded")
self.dataHolder = data
completion()
}
task.resume()
}
}
Now in collectionViewDidSelectItemAt make this changes
func collectionView (_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dataManager.downloadAttachment(id: attachments[indexPath.row].attachmentID,completionHandler: { data in
if let cell = collectionView.cellForItem(at: indexPath),
let data = dataManager.dataHolder,
let image = UIImage.init(data: data){
attachmentImage.image = image
attachmentImage.isHidden = false
}
})
}
Upvotes: 1