Reputation: 411
When I scroll to the bottom of the UITableView the app is suppose to call a function ("CallAlamo(url: nextSearchURL)"), which just appends new content to array, then call tableView.reloadData(), and the tableview is then updated with the more content. However, the tableView freezes completely for about 2-3 seconds during this process. How can I get it to not freeze and work like most table views do in other apps where the new content is being loaded and the user is free to move the tableview.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastElement = posts.count - 1
if indexPath.row == lastElement {
callAlamo(url: nextSearchURL) //appends new content to array
tableView.reloadData()
}
}
UPDATE
This is what callAlamo does:
func callAlamo(url : String){
Alamofire.request(url).responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
})
}
func parseData(JSONData : Data){
do{
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
//print(readableJSON)
if let tracks = readableJSON["tracks"] as? JSONStandard{
nextSearchURL = tracks["next"] as! String
if let items = tracks["items"] as? [JSONStandard]{
//print(items) //Prints the JSON information from Spotify
for i in 0..<items.count{
let item = items[i]
let name = item["name"] as! String
let previewURL = item["preview_url"] as! String
if let album = item["album"] as? JSONStandard{
if let images = album["images"] as? [JSONStandard],let artist = album["artists"] as? [JSONStandard]{
let imageData = images[0] //this changes the quality of the album image (0,1,2)
let mainImageURL = URL(string: imageData["url"] as! String)
let mainImageData = NSData(contentsOf: mainImageURL!)
let mainImage = UIImage(data: mainImageData as! Data)
let artistNames = artist[0]
let artistName = artistNames["name"] as! String
posts.append(post.init(mainImage: mainImage, name: name, artistName: artistName, previewURL: previewURL))
self.tableView.reloadData()
}
}
}
}
}
} catch{
print(error)
}
}
UPDATE 2
Using @Anbu.Karthik choice 2:
Question 1: is "imageData" going to be my "mainImagedata"?
Question 2: I get an error in the Alamofire.request... saying "Extra argument 'method' in call" and when i delete it, i get an error that says "NSData? has no subscript members"
Upvotes: 2
Views: 1814
Reputation: 791
Very bad code design, you should pass the url to the cell and let it do the fetching and parsing, and you are doing this on the main queue. You can do this using(using another queue) DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).async
. IDK if Alamofire calls your closure on the main queue, but it look like it does the request on it. And don't forget to get back on the main queue when you want do to UI using DispatchQueue.main.async
UPDATE: I hope that it was clear that reloadData(), kinda gives you an infinite loop, and you should call these outside the TableViewDataSource funcitons
UPDATE 2: I don't see it here, but you should use tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
and use in it let cell = tableView.dequeueReusableCell.....
Upvotes: 2