Experimenting with Swift3, Alamofire and AlamofireImage. I am trying to display some Instagram images in a tableview. I have a data.json
file of Places retrieved using Alamofire which look like this:
{
"places" : [
{ "name" : "place1", "url" : "http://instagramImage1.jpg" },
{ "name" : "place2", "url" : "http://instagramImage2.jpg" },
{ "name" : "place3", "url" : "http://instagramImage3.jpg" },
]
}
I have setup PlaceTableViewCell
with a UIImageView
and attached it to an outlet in the corresponding controller.
I also have a PlaceTableViewController
which includes:
var places = [Place]() //empty array to store places
In viewDidLoad()
method I call a private function:
loadJson()
and the function looks like this:
private func loadJson() {
Alamofire.request("https://example.com/data.json").responseJSON { response in
if let JSON = response.result.value as? [String : Any],
let places = JSON["places"] as? [[String : String]] {
for place in places {
//should I call loadImage() function here?
}
}
}
}
I also have a model for each place in the JSON file:
import UIKit
class Place {
var name: String
var url: String
init?(name: String, url: String) {
self.name = name
self.url = url
}
}
QUESTION
I'm not sure where to go from here. I would like to use AlamofireImage (which I have included in my project) to download each image but can I do this in a loop of some sort? I would also like to show each image in a new table row. Any advice and code examples would be much appreciated.
I would recommend not fetch the image in loadJSON
.
Why?
There could be a large number of photos coming back in the initial request, and the user may never even scroll down in the application far enough to see some of them.
On top of that, if you initialize too many requests simultaneously, some of the requests may time out while waiting for other requests to finish. So this is probably not the best solution.
So, now coming to the solution. It makes sense to download the image data for only the cells that the user is attempting to view.
TableView
has a delegate method for this purpose only
optional func tableView(_ tableView: UITableView,
willDisplay cell: UITableViewCell,
forRowAt indexPath: IndexPath)
Use this method to load the images.
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView,
willDisplay cell: UITableViewCell,
forRowAt indexPath: IndexPath) {
let photoURL = places[indexPath.row].url
// fetch this photo from web using URL
// get the table view cell and update the image
if let cell = self.tableView.cellForRow(at: indexPath) as UITableViewCell {
cell.imageView.image = //fetchPhoto
}
}
}