Reputation: 10703
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.
Upvotes: 0
Views: 1993
Reputation: 2100
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
}
}
}
Upvotes: 1
Reputation: 2252
You can use below code in your tableview controller to populate image in cell. For that you will also require to create one cell in tableview or create custom cell with xib. My code is for loading the custom cell from xib take a look.
//MARK:- TableView Delegate and DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection sectionIndex: Int) -> Int {
return places.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200//or cell height you want
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "PlaceCell") as? PlaceCell
if cell == nil {
cell = (loadFromNibNamed(viewClass: PlaceCell.self) as! PlaceCell)
}
cell?.ivCategory.af_setImage(withURL: URL(string: places[indexPath.row].url))
return cell!
}
Also note that you will have to reload tableview once you get response from api.
Upvotes: 0