OriginalAlchemist
OriginalAlchemist

Reputation: 411

UITableView freezes when scrolling to bottom and adding new rows

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

Answers (1)

Stefan Scoarta
Stefan Scoarta

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

Related Questions