Reputation: 13199
I am using a tableViewController
on my Swift 3.0
project. I want to get the number of rows of my tableview from a request and I am using Alamofire 4.0
for that purpose.
I saw that to return values from Alamofire
you have to set a completionHandler
(How to return value from Alamofire) but Xcode do not let me set it on tableView
method.
This is the code that I have tried with set/get methods:
var numRows = 0
func setRows(numRows : Int){
self.numRows = numRows
}
func getRows() -> Int{
return self.numRows
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var JSON = [[String : AnyObject]]()
Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
switch(response.result) {
case .success(_):
JSON = response.result.value as! [[String : AnyObject]]!
self.setRows(numRows: JSON.count)
break
case .failure(_):
print("Error")
break
}
}
return self.getRows()
}
but I am not able to make it work. I know that Alamofire request is asynchronous and is the problem that I am facing but I am not able to set completionHandler on tableView
function.
P.S: I also have tried to make synchronous Alamofire (making an asynchronous alamofire request synchronous) but completion block again appears and I am not able to set it to tableView method (I do not know if it is possible to set it on that method or I am doing it in the wrong way).
I have tried adding completion:(Int) -> Void
to my tableView method but Xcode does not allow me to do that.
What should I do to set the number of rows after doing the request?
Thanks in advance!
Upvotes: 2
Views: 1366
Reputation: 15512
This is the small example how it is possible to do.
Firstly create property of the rows and set init value that is 0 for example :
var rowCount = 0
After that create an elegant function that will fetch data and update rowCount
,also this function will update our tableview
example :
func elegantFuntionToUpdateRowCount() {
var JSON = [[String : AnyObject]]()
Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
switch(response.result) {
case .success(_):
JSON = response.result.value as! [[String : AnyObject]]!
rowCount = JSON.count
tableView reloadData
break
case .failure(_):
print("Error")
break
}
}
}
And implement numberOfRowsInSection
.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowCount
}
It is small example how it is possible to do but try to read a bit about software architecture.
Upvotes: 0
Reputation: 2685
I'm doing something like this:
table of items that will be in tableView
var positionsTable = [[String : AnyObject]]()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return positionsTable.count
}
from request i get items and reload tableView
Alamofire.request(.GET, url, headers: headers, encoding: .JSON)
.responseJSON { (response) in
print(response)
self.positionsTable = response.result.value
self.tableView.reloadData()
}
}
Upvotes: 3
Reputation: 8465
You are thinking about this the wrong way. You don't need to set the completionHandler on the tableView.
The viewController's job is to control the flow of information.
This will cause the tableView to request the number of rows again, and update the entire tableView's contents.
Also note that when dealing with UI, you should always use async networking methods. Your UI should make the user aware that something is processing, and then update the screen when its done.
Upvotes: 2