Json request retrieving results but only displaying the first result - ios

I have a tableview which is getting data from an api request, from that request its only displaying the first result.
//MARK:-- Computed vars
var listOfLodges = [LodgeDetail](){
didSet{
DispatchQueue.main.async {
self.tableView.reloadData()
self.navigationItem.title = "\(self.listOfLodges.count) lodges found"
print("\(self.listOfLodges.count) lodges found") // returns 11 lodges
print(" ")
}
}
}
this displays 11 returned results, all the data is different.
//MARK: -- ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
//MARK:-- Setting up Table view
#objc func setDelegate(){
let landing = LandingViewController()
landing.delegate = self
}
override func numberOfSections(in tableView: UITableView) -> Int {
return listOfLodges.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
this is probably where my errors are, I am unsure of what could be going wrong?
// possible errors here
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for:indexPath)
let lodge = listOfLodges[indexPath.row]
let rating: String = String(lodge.rating!)//careful force unwrapping
print(rating) // prints the same 4.2
print(lodge.name) //prints the same name
return cell
}
}
//MARK:-- Functions called on did load
extension ListViewController{
func loadData(){
let lodgeRequest = LodgeRequest(lat:passedLat, long:passedLong)
lodgeRequest.getLodges{[weak self] result in
switch result{
case.failure(let error):
print(error)
case.success(let lodges):
self?.listOfLodges = lodges
}
}
}
}

Change
let lodge = listOfLodges[indexPath.row]
to
let lodge = listOfLodges[indexPath.section]
As you only have one row per section then indexPath.row is always 0 so first item is displayed for all sections

Related

How to optimize loading from Firestore to Tableview

My View Controller has a Tableview with 2 segments. Depending on which Segment is selected, the Tableview displays a different set of data.
#IBAction func didChangeSegment(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0 {
model.getRecipes(starredTrue: false)
}
else if sender.selectedSegmentIndex == 1 {
model.getRecipes(userAdded: true)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return recipe.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MealPlanCell", for: indexPath) as! MealPlanCell
let recipeInTable = recipe[indexPath.row]
cell.displayRecipe(recipe: recipeInTable, indexPathRow: indexPath.row)
return cell
}
And this is how model.getRecipes() gets data from Firestore before returning it to the Tableview:
let recipeQuery = db.collection("recipes")
let docRef = recipeQuery.document(documentId)
docRef.getDocument { document, error in
if let error = error as NSError? {
self.errorMessage = "Error getting document: \(error.localizedDescription)"
}
else {
if let document = document {
do {
self.recipe = try document.data(as: Recipe.self)
let recipeFromFirestore = Recipe(
id: documentId,
title: self.recipe!.title ?? "")
self.recipes.append(recipeFromFirestore)
}
catch {
}
}
DispatchQueue.main.async {
self.delegateRecipes?.recipesRetrieved(recipes: self.recipes)
}
}
}
The issue I'm having is that the Tableview takes a very long time to display data. It appears this is because it has to wait for the model to finish loading all the data from Firestore every time I select one of the segments.
How can I optimize this process? Is it possible to have the TableView load/display cell by cell, instead of needing to wait for all data to be loaded?
Any guidance is much appreciated!

showing an error as has need to conform the protocol

This is my code:-
Model:-
class QuestionListModel: NSObject {
var optionsModelArray:[OptionsModel] = []
var question:String!
init(dictionary :JSONDictionary) {
guard let question = dictionary["question"] as? String
else {
return
}
if let options = dictionary["options"] as? [String]{
print(options)
print(options)
for values in options{
print(values)
let optionmodel = NH_OptionsModel(values: values)
self.optionsModelArray.append(optionmodel)
}
}
self.question = question
// print(self.dataListArray33)
}
}
optionModel:-
class OptionsModel: NSObject {
var values:String?
init(values:String) {
self.values = values
print( self.values)
}
}
in viewmodel:-
var questionsModelArray:Array<NH_QuestionListModel>? = []
init(withdatasource newDatasourceModel:NH_QuestionDataSourceModel) {
datasourceModel = newDatasourceModel
print(datasourceModel.dataListArray?.count)
self.questionsModelArray = datasourceModel.dataListArray
print(self.questionsModelArray)
print(datasourceModel.dataListArray)
}
func numberOfSections() -> Int{
return (self.questionsModelArray?.count)!
}
func titleForHeaderInSection(atindexPath indexPath: IndexPath) -> QuestionListModel {
return self.questionsModelArray![indexPath.row]
}
func numberOfRowsInSection(indexPath:IndexPath) -> Int {
if let questionModel = self.questionsModelArray?[indexPath.section]{
return questionModel.optionsModelArray.count
}
else{
return 0
}
}
func datafordisplay(atindex indexPath: IndexPath) -> OptionsModel{
let questionModel = self.questionsModelArray?[indexPath.section]
return questionModel!.optionsModelArray[indexPath.row]
}
And in ViewController:-
func numberOfSections(in tableView: UITableView) -> Int {
return questionViewModel.numberOfSections()
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: IndexPath) -> UIView? {
// let headercell = Bundle.main.loadNibNamed("HeaderCell", owner: self, options: nil)?.first as! NH_questionheader
let identifier = "HeaderCell"
var headercell: NH_questionheader! = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_questionheader
if headercell == nil {
tableView.register(UINib(nibName: "NH_questionheader", bundle: nil), forCellReuseIdentifier: identifier)
headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_questionheader
}
headercell.setReviewData(reviews:questionViewModel.titleForHeaderInSection(atindexPath:section))
return headercell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: IndexPath) -> Int {
return questionViewModel.numberOfRowsInSection(indexPath: section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "Cell"
var cell: CellTableViewCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? CellTableViewCell
if cell == nil {
tableView.register(UINib(nibName: "CellTableViewCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? CellTableViewCell
}
cell.contentView.backgroundColor = UIColor.clear
cell.setOptions(Options1: questionViewModel.datafordisplay(atindex: indexPath))
print("Section \(indexPath.section), Row : \(indexPath.row)")
return cell
}
my json file:-
{
"data":[
{
"question": "Gender",
"options": ["Male","Female"]
},
{
"question": "How old are you",
"options": ["Under 18","Age 18 to 24","Age 25 to 40","Age 41 to 60","Above 60"]
}, {
"question": "I am filling the Questionnaire for?",
"options": ["Myself","Mychild","Partner","Others"]
}
]
}
This is my data .So i need to display the questions in header and options in the cell for index .But showing as error as UITableview has need to conform the protocol UITableviewDataSource.
Also showing error as Index out of range.
How to do.....
I think you are not assign a datasource to your view controller. So please assign it in your ViewDidLoad of your view controller
override func viewDidLoad() {
super.viewDidLoad()
self.yourtableview.delegate = self
self.yourtableview.dataSource = self
// Do any additional setup after loading the view.
}
This error usually occurs when you fail to implement the required methods of a protocol. In this case the methods would be :
cellForRowAt
numberOfRowsInSection
Since you already have them implemented in your view controller chances are that you might have failed to set the datasource for the table view.
Refer to this
https://developer.apple.com/documentation/uikit/uitableviewdatasource
your view controller cannot find the data source and delegate for the table view. make sure you have assigned the data source and delegate
self.yourtableview.delegate = self
self.yourtableview.dataSource = self
and also make sure that your controller also inherit the UITableViewDelegate and UITableViewDataSource like this
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource
To achieve what you want, you should set your VC as the delegate and datasource of your table.
Option 1, do it dynamically:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}
Option 2, from your storyboard (example below):
After this, you should use the following datasource functions of UITableView:
// return number of questions
func numberOfSections(in tableView: UITableView) -> Int
// return number of options per question (indicated by section)
func tableView(UITableView, numberOfRowsInSection: Int) -> Int
You haven't correctly declared the numberOfRowsInSection function; section is an Int, not an IndexPath. As a result you have not implemented the mandatory functions of UITableViewDataSource.
You want:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return questionViewModel.numberOfRowsIn(section: section)
}
With an appropriate change in your view model:
func numberOfRowsIn(section:Int) -> Int {
return self.questionsModelArray?[section].optionsModelArray.count ?? 0
}
I would also suggest that you review your use of implicitly unwrapped optionals and force unwrapping; this is just asking for crashes.
For example, there is no reason for the question property of QuestionListModel to be String!; just declare it as String and make your initialiser failable. Better yet, use Codable to create your model from JSON and get rid of all of that code.
You can eliminate the force unwrapping in numberOfSections too:
func numberOfSections() -> Int {
return self.questionsModelArray?.count ?? 0
}
I would also suggest you make QuestionListModel a struct rather than an NSObject subclass.
If I were you I would re-factor to remove the view model, it is adding unnecessary complexity in this case, and use Codable for your JSON deserialisation:
struct Questions: Codable {
enum CodingKeys: String, CodingKey {
case questions = "data"
}
var questions: [Question]
}
struct Question: Codable {
var question: String
var options: [String]
}
Your view controller then becomes much simpler:
class ViewController: UIViewController, UITableViewDatasource {
var questionData: Questions?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "NH_questionheader", bundle: nil), forCellReuseIdentifier: "HeaderCell")
tableView.register(UINib(nibName: "CellTableViewCell", bundle: nil), forCellReuseIdentifier: "Cell")
// You don't show how you load your JSON, but assuming you have it in an instance of `Data` called `jsonData`:
do {
self.questionData = try JSONDecoder().decode(Questions.self, from: jsonData)
} catch {
print("Error decoding JSON: \(error.localizedDescription)")
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: IndexPath) -> UIView? {
let identifier = "HeaderCell"
guard let questionData = self.questionData,
let headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_questionheader else {
return nil
}
headercell.label.text = questionData.questions[section].question
return headercell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.questionData?.questions[section].options.count ?? 0
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.questionData?.questions.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "Cell"
// Note, I have used force unwrapping and a forced downcast here as if either of these lines fail you have a serious problem and crashing is the simplest way of finding it during development
let option = self.questionData!.questions[indexPath.section].options[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath ) as! CellTableViewCell
cell.contentView.backgroundColor = .clear
cell.label.text = option
return cell
}
}
Once you have this basic approach working you can try and add a view model if you like.

Google Places not loading into TableView

I have a UIViewController which presents another UIViewController as a UISearchResultsController.
I would like this searchResultsController to display GooglePlaces upon search.
I am getting all the autocomplete predictions printed out in the console, however, the UITableView is not loading the data.
Here is my function;
func updateSearchResults(for searchController: UISearchController) {
searchController.searchResultsUpdater = self
if searchController.isActive {
searchController.searchResultsController?.view.isHidden = false
}
if searchController.searchBar.text == "" {
self.searchResults.removeAll()
} else {
guard let query = searchController.searchBar.text else { return }
GMSPlacesClient.shared().autocompleteQuery(query, bounds: nil, filter: filteredResults) { (predictions, error) in
if error != nil {
print(error as Any)
return
} else {
guard let searchPredictions = predictions else { return }
self.searchResults = searchPredictions
print("PREDICTION: \(searchPredictions)")
DispatchQueue.main.async {
self.resultsTableView.reloadData()
}
}
}
}
}
Sanitation Checks
TableView Delegate
TableView DataSource
Predictions
numberOfRowsInSection
1 & 2 are set to self.
3 is printing;
GMSAutocompletePrediction 0x6000037f0450: "England Street, Charlotte, NC, USA", id: EiJFbmdsYW5kIFN0cmVldCwgQ2hhcmxvdHRlLCBOQywgVVNB, types: (
route,
geocode
4 is giving me the correct amount of predictions
I am following the custom implementation from google here;
https://developers.google.com/places/ios-sdk/autocomplete#get_place_predictions_programmatically
Under 'Get place predictions programmatically'
As always any help appreciated.
Update: TableView Methods
extension SearchResultsController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let resultsCell = resultsTableView.dequeueReusableCell(withIdentifier: resultsCellIdentifier, for: indexPath) as! ResultsCell
let resultsAttributedFullText = searchResults[indexPath.row].attributedFullText.string
resultsCell.textLabel?.text = resultsAttributedFullText
return resultsCell
}
UPDATE: cellForRowAt
Upon further inspection of my cellForRowAt function;
let results = searchResults[indexPath.row].placeID
printing results to the console doesn't give me any output.
UPDATE:
Adding breakpoint result at self.searchResults = searchPredictions
UPDATE:
In the console I'm getting the following error;
[BoringSSL] nw_protocol_boringssl_get_output_frames(1300) [C3.1:2][0x7ffd627057e0] get output frames failed, state 8196
Not sure if this could be connected to my issue or not but noting it anyway.
Could you replace the following:
DispatchQueue.main.async {
self.resultsTableView.reloadData()
}
to
DispatchQueue.main.async {
searchController.searchResultsController.resultsTableView.reloadData()
}

Limit the amount of cells shown in tableView, load more cells when scroll to last cell

I'm trying to set up a table view that only shows a specific amount of cells. Once that cell has been shown, the user can keep scrolling to show more cells. As of right now I'm retrieving all the JSON data to be shown in viewDidLoad and storing them in an array. Just for example purposes I'm trying to only show 2 cells at first, one the user scrolls to bottom of screen the next cell will appear. This is my code so far:
class DrinkViewController: UIViewController {
#IBOutlet weak var drinkTableView: UITableView!
private let networkManager = NetworkManager.sharedManager
fileprivate var totalDrinksArray: [CocktailModel] = []
fileprivate var drinkImage: UIImage?
fileprivate let DRINK_CELL_REUSE_IDENTIFIER = "drinkCell"
fileprivate let DRINK_SEGUE = "detailDrinkSegue"
var drinksPerPage = 2
var loadingData = false
override func viewDidLoad() {
super.viewDidLoad()
drinkTableView.delegate = self
drinkTableView.dataSource = self
networkManager.getJSONData(function: urlFunction.search, catagory: urlCatagory.cocktail, listCatagory: nil, drinkType: "margarita", isList: false, completion: { data in
self.parseJSONData(data)
})
}
}
extension DrinkViewController {
//MARK: JSON parser
fileprivate func parseJSONData(_ jsonData: Data?){
if let data = jsonData {
do {
let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : AnyObject]//Parses data into a dictionary
// print(jsonDictionary!)
if let drinkDictionary = jsonDictionary!["drinks"] as? [[String: Any]] {
for drink in drinkDictionary {
let drinkName = drink["strDrink"] as? String ?? ""
let catagory = drink["strCategory"] as? String
let drinkTypeIBA = drink["strIBA"] as? String
let alcoholicType = drink["strAlcoholic"] as? String
let glassType = drink["strGlass"] as? String
let drinkInstructions = drink["strInstructions"] as? String
let drinkThumbnailUrl = drink["strDrinkThumb"] as? String
let cocktailDrink = CocktailModel(drinkName: drinkName, catagory: catagory, drinkTypeIBA: drinkTypeIBA, alcoholicType: alcoholicType, glassType: glassType, drinkInstructions: drinkInstructions, drinkThumbnailUrl: drinkThumbnailUrl)
self.totalDrinksArray.append(cocktailDrink)
}
}
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}
DispatchQueue.main.async {
self.drinkTableView.reloadData()
}
}
//MARK: Image Downloader
func updateImage (imageUrl: String, onSucceed: #escaping () -> Void, onFailure: #escaping (_ error:NSError)-> Void){
//named imageData because this is the data to be used to get image, can be named anything
networkManager.downloadImage(imageUrl: imageUrl, onSucceed: { (imageData) in
if let image = UIImage(data: imageData) {
self.drinkImage = image
}
onSucceed()//must call completion handler
}) { (error) in
onFailure(error)
}
}
}
//MARK: Tableview Delegates
extension DrinkViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return numberOfRows
return drinksPerPage
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = drinkTableView.dequeueReusableCell(withIdentifier: DRINK_CELL_REUSE_IDENTIFIER) as! DrinkCell
//get image from separate url
if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{//index out of range error here
updateImage(imageUrl: image, onSucceed: {
if let currentImage = self.drinkImage{
DispatchQueue.main.async {
cell.drinkImage.image = currentImage
}
}
}, onFailure: { (error) in
print(error)
})
}
cell.drinkLabel.text = totalDrinksArray[indexPath.row].drinkName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{
updateImage(imageUrl: image, onSucceed: {
}, onFailure: { (error) in
print(error)
})
}
performSegue(withIdentifier: DRINK_SEGUE, sender: indexPath.row)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastElement = drinksPerPage
if indexPath.row == lastElement {
self.drinkTableView.reloadData()
}
}
}
I saw this post: tableview-loading-more-cell-when-scroll-to-bottom and implemented the willDisplay function but am getting an "index out of range" error.
Can you tell me why you are doing this if you are getting all results at once then you don't have to limit your display since it is automatically managed by tableview. In tableview all the cells are reused so there will be no memory problem. UITableViewCell will be created when it will be shown.
So no need to limit the cell count.
I dont now what you are doing in your code but:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastElement = drinksPerPage // no need to write this line
if indexPath.row == lastElement { // if block will never be executed since indexPath.row is never equal to drinksPerPage.
// As indexPath starts from zero, So its value will never be 2.
self.drinkTableView.reloadData()
}
}
Your app may be crashing because may be you are getting only one item from server.
If you seriously want to load more then you can try this code:
Declare numberOfItem which should be equal to drinksPerPage
var numberOfItem = drinksPerPage
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return numberOfRows
return numberOfItem
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == numberOfItem - 1 {
if self.totalDrinksArray.count > numberOfItem {
let result = self.totalDrinksArray.count - numberOfItem
if result > drinksPerPage {
numberOfItem = numberOfItem + drinksPerPage
}
else {
numberOfItem = result
}
self.drinkTableView.reloadData()
}
}
}

Populating Cells in a tableView from API Call

I am forced to use an asynchronous call (I guess closure in swift) to get Data I need using an SDK (APIWrapper). I'm finding that the view is being initalized before I am able to get the data that I need.
So my 1st question to y'all is, how can I get my cells to bring in the data that I need to the table view before the view loads? Then, why would I want to use an asyncronous call at this point
import APIWrapper
import UIKit
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let provider = APIWrapper
var categories = [String]()
//define number of cells
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
categories = []
self.getCells()
print("count " , self.categories.count)
return(self.categories.count)
}
//get number of cells
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "categories")
cell.textLabel?.text = categories[indexPath.row]
return(cell)
}
private func getCells(){
provider?.getCategoriesWithCallback { (response, error) -> () in
if error == nil {
print("response ", response)
self.updateTableViewWithCategories(categories: response as! [APIWrapperCategory])
}
else {
print("FUCKK")
}
}
}
private func updateTableViewWithCategories(categories: [APIWrapperCategory]){
for category in categories{
print("category obj " , category)
print("category name " , category.name)
}
}
}
The output from my console looks like
count 0
count 0
count 0
count 0
response Optional([<APIWrapperCategory: 0x6000002a0300>])
category obj <ZDKHelpCenterCategory: 0x6000002a0300>
category name General
response Optional([<ZDKHelpCenterCategory: 0x6180002a30c0>])
category obj <ZDKHelpCenterCategory: 0x6180002a30c0>
category name General
response Optional([<ZDKHelpCenterCategory: 0x6180002a30c0>])
category obj <ZDKHelpCenterCategory: 0x6180002a30c0>
category name General
response Optional([<ZDKHelpCenterCategory: 0x6180002a3300>])
category obj <ZDKHelpCenterCategory: 0x6180002a3300>
category name General
You are getting data for your table view from the data source method of the tableview.
To get data from an API call, call self.getCells() method in viewDidLoad() method of your view controller like this:
override func viewDidLoad() {
//your code here
//get cells data
self.getCells()
}
And add your api response data to table view data source as:
private func updateTableViewWithCategories(categories: [APIWrapperCategory]){
self. categories = []
for category in categories{
print("category obj " , category)
print("category name " , category.name)
self. categories.append(category.name)
}
//reload table view here
DispatchQueue.main.async {
self.yourTableView.reloadData()
}
}
and change the delegate method as:
//define number of cells
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("count " , self.categories.count)
return(self.categories.count)
}
So I ended up using viewWillAppear and changed a few things on the way data is returned to make the cells populate so here's the code, I hope this can help someone else out
#IBOutlet weak var tableView: UITableView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.getCategoriesFromZendesk()
}
//define number of cells
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("count " , self.categories.count)
return self.categories.count
}
//get number of cells
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//Add Label to the Prototype Cell
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "categories")
cell.textLabel?.text = categories[indexPath.row]
return(cell)
}
private func getCategories(){
self.categories = []
provider?.getCategoriesWithCallback { (response, error) -> () in
if error == nil {
print("response ", response?.map{($0 as AnyObject as? APIWrapperCategory)?.name ?? ""} ?? "empty")
self.updateTableViewWithCategories(categories: response as? [APIWrapperCategory])
}
else {
print("FUCKK")
}
}
}
private func updateTableViewWithCategories(categories: [APIWrapperCategory]?){
self.categories = categories?.flatMap{$0.name} ?? []
tableView.reloadData()
}

Resources