mohammadreza
mohammadreza

Reputation: 235

iOS Swift Custom Cell Function

I have a TableView and custom cell. in my custom cell i have this function:

func URLRequest(bookId : String) {


    let headers = [
        "Authorization": "Bearer",
        "Accept": "application/json"
    ]

    let url = "http://example.com/api/v1/books/\(bookId)/related"

    let URLRequest = NSMutableURLRequest(URL: NSURL(string: url)!)
    URLRequest.cachePolicy = NSURLRequestCachePolicy.ReturnCacheDataElseLoad


    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    Alamofire.request(.GET, url, headers:headers)
        .validate()
        .responseJSON { response in


            switch response.result {
            case .Success:
                if let jsonData = response.result.value {

                    dispatch_async(dispatch_get_main_queue(), {

                        print("Custom Cell")

                        return
                    })
                    self.tableRefresh()
                    UIApplication.sharedApplication().networkActivityIndicatorVisible = false

                }
            case .Failure(let error):
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                print(error)
            }

    }

}

and I run this function in my tableView:

if indexPath.row == 4 {
     let cell = tableView.dequeueReusableCellWithIdentifier("relatedCell", forIndexPath: indexPath) as! RelatedBookTableViewCell
     cell.URLRequest(self.bookID)
     return cell
}

But the problem is every time that I scroll the table view this request(URLRequest) run again. I want to send this request once and when the view did load.

where is my problem?

P.S I try to load my URLRequest in custom cell with this

override init()

but I can't pass bookId value from tableview to custom cell and return nil.

thanks

Upvotes: 1

Views: 686

Answers (3)

Ram Mani
Ram Mani

Reputation: 1019

put the table.dequeReusableCellWithIdentifier out side the if condition

and write like this

    let cell = tableView.dequeueReusableCellWithIdentifier("relatedCell", forIndexPath: indexPath) as! RelatedBookTableViewCell

    if indexPath.row == 4 {
         cell.URLRequest(self.bookID)
     }
return cell

Upvotes: 0

Sealos
Sealos

Reputation: 562

The issue you're facing is occurring because the table view cells get reused by the table view. That means that the OS only keeps few cells in memory, but when you are scrolling, it moves them in the view.

Anyways, there are two ways of solving this issue:

The first one involves having the book information in the table view controller (With a dictionary or an array), and when you're initializing the cell, just set the properties in the cell. Preferred.

The second one is storing the current bookId in the cell, and if the cell currently is displaying that book id, just return. This is not recommended.

Remember, the cell is not a controller, it should only be used to store data and modify the view. All the logic should be in the table view controller.

Upvotes: 2

Pavel Gatilov
Pavel Gatilov

Reputation: 2590

The thing is that you trying to load it in your cell. And every time when you will scroll to a new cell, cellForRowAtIndexPath will call your URLRequest again. What you really need to do, is to preload your data, before. In other words, you have to execute your request somewhere on viewDidLoadin your viewController(or in specific model class), store results in array(or any other collection type) and then just pass static data into cells. Calling network requests inside UITableViewCell subclass will end up with inefficient memory and traffic usage.

Upvotes: 1

Related Questions