With the help of some videos I was able to parse my Firestore data into an array of arrays, but now I'm having a bit of trouble figuring out how to use this data to populate my tableview.
The idea is to use the 'dow' field for the Sections and the 'workouts' field for the Rows.
If I print the first index of my array, this is the output that I'm getting...
[Days(dow: "Tuesday", workouts: [Effortflex.Workouts(workout: "Back")]), ..., ...]
I feel like I'm missing a step here. Can someone assist me with this please.
self.loadData { (Bool) in
if Bool == true {
print(self.dataArray[0])
self.dayCount = self.dataArray.count
}
}
struct Workouts {
var workout : String
}
struct Days {
var dow : String
var workouts : [Workouts]
var dictionary: [String : Any] {
return ["dow" : dow]
}
}
extension Days {
init?(dictionary: [String : Any], workouts : [Workouts]) {
guard let dow = dictionary["dow"] as? String else { return nil }
self.init(dow: dow, workouts: workouts)
}
}
//MARK: - Load Data
func loadData(completion: #escaping (Bool) -> ()){
let group = DispatchGroup()
self.rootCollection.getDocuments (completion: { (snapshot, err) in
if let err = err
{
print("Error getting documents: \(err.localizedDescription)");
}
else {
guard let dayDocument = snapshot?.documents else { return }
for day in dayDocument {
group.enter()
self.rootCollection.document(day.documentID).collection("Workouts").getDocuments { (snapshot, err) in
var workouts = [Workouts]()
guard let workoutDocument = snapshot?.documents else { return }
for workout in workoutDocument {
let workoutString = workout.data()["workout"] as! String
let newWorkout = Workouts(workout: workoutString)
workouts.append(newWorkout)
}
let dayTitle = day.data()["dow"] as! String
let newDay = Days(dow: dayTitle, workouts: workouts)
self.dataArray.append(newDay)
group.leave()
}
}
}
group.notify(queue: .main){
completion(true)
}
})
}
I made an example that you can use as a basis to be able to use your structure.
Make your array into a list and persist in the scope of your class so that the methods of the tableView can access it. You can transform as follows:
let dataList = dataArray.flatMap{$0}
Then use the data to display on the tableView
func numberOfSections(in tableView: UITableView) -> Int {
dataList.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataList[section].workouts.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return dataList[section].dow
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testcell", for: indexPath)
cell.textLabel?.text = dataList[indexPath.section].workouts[indexPath.row].workout
return cell
}
Related
Please advice how can I paginate my tableview. I get data from the CocktailDB API and parse JSON with Decodable. There are categories and drinks from these categories.
I want to firstly load 10 drinks and then load more when I scroll to the bottom of the page.
I considered using willDisplay method by tableview.
Thank you in advance!
My code:
class ViewController: UIViewController {
struct OneCategory {
let name : String
var drinks : [Drink]
}
var drinks = [Drink]()
var categories = [OneCategory]()
var selectedCategoriesArr: [String] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
loadAllCategories()
}
func loadAllCategories() {
let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if let error = error {
print(error)
return
}
do {
let result = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
let categoryNames = (result["drinks"] as! [[String:String]]).map{$0["strCategory"]!}
let group = DispatchGroup()
for category in categoryNames {
let categoryURLString = "https://www.thecocktaildb.com/api/json/v1/1/filter.php?c=\(category)"
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let categoryURL = URL(string: categoryURLString)!
group.enter()
let categoryTask = URLSession.shared.dataTask(with: categoryURL) { (categoryData, _, categoryError) in
defer {
group.leave()
}
if let categoryError = categoryError {
print(categoryError)
return
}
do {
let drinks = try JSONDecoder().decode(Response.self, from: categoryData!).drinks
self.categories.append(OneCategory(name: category, drinks: drinks))
} catch {
print(error)
}
}
categoryTask.resume()
}
group.notify(queue: .main) {
self.tableView.reloadData()
}
} catch {
print(error)
}
}.resume()
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return categories.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return categories[section].name
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories[section].drinks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "drinkCell") as! DrinkCell
let category = categories[indexPath.section]
let drink = category.drinks[indexPath.row]
cell.drinkName.text = drink.strDrink
let url = drink.strDrinkThumb
cell.drinkImage.downloaded(from: url)
return cell
}
}
Models:
struct Response:Decodable {
var drinks: [Drink]
}
struct Drink:Decodable {
var strDrink: String
var strDrinkThumb: String
}
struct Categories:Decodable {
var drinks: [Category]
}
struct Category:Decodable {
var strCategory: String
}
I wanna ask how to implement the files as sections depends on userId then show all again in the tableview
I'm started build simple project i fetched json file as decoder and show all in table view
func fetchUsers(using url: String){
let url = URL(string: url)!
let _ = URLSession.shared.dataTask(with: url){ (data,response,error)
in
guard let data = data else {return}
do{
let objects = try JSONDecoder().decode([User].self, from: data) // decode * ( Codable )
self.users = objects
} catch{
print("error loading data cause: \(error)")
}
}.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "users",for: indexPath) as? customeCellTableViewCell{
let indexRow = users[indexPath.row]
cell.dataModel(forModel: indexRow)
return cell
}
return UITableViewCell()
}
private func numberOfUsers(in users: [User]) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return numberOfUsers(in: self.users)
}
Like #vadian mentions tuples should be avoided for this so here is an improved solution.
Instead of a tuple we can use a struct to hold the grouped data
struct UsersByID {
let id: Int
var users : [User]
}
then change the load function to
func load(withUsers users: [User]) {
let dict = Dictionary(grouping: users) { return $0.userID }
usersByID = dict.map { (key, values) in
return UsersByID(id: key, users: values)
}.sorted(by: { $0.id < $1.id })
}
The rest of the code is the same but replace key with id and value with users
Old solution
First create a dictionary to hold your sections (keys) and rows (values) as a property in the view controller
var usersByID = [(key: Int, value: [User])]()
then fill that dictionary using grouping:by: using the array from json
func load(withUsers users: [User]) {
usersByID = Dictionary(grouping: users, by: { user in
user.userID }).sorted(by: { $0.0 < $1.0})
}
then the table view functions use this dictionary
override func numberOfSections(in tableView: UITableView) -> Int {
return usersByID.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return usersByID[section].value.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return String(usersByID[section].key)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
let user = usersByID[indexPath.section].value[indexPath.row]
cell.textLabel?.text = user.title
//...
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return datesArr.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (contractsDict.keys.contains(datesArr[section])) {
return contractsDict[datesArr[section]]!.count
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ContractsCollectionViewCell
DispatchQueue.main.async {
if (self.contractsDict.keys.contains(self.datesArr[indexPath.section])) {
for _ in 0..<(self.contractsDict[self.datesArr[indexPath.section]]!.count) {
cell.contract = self.contractsDict[self.datesArr[indexPath.section]]![indexPath.row]
cell.delegate = self
}
}
}
return cell
}
}
}
ContractServices.shared.fetchAllContracts(completion: { (contracts, err) in
DispatchQueue.main.async {
if (err != nil) {
print(err!, "1323")
return
}
for contract in (contracts?.data)! {
self.allContractsArr.append(contract)
if let callDate = contract.revdat {
let formatterGet = DateFormatter()
formatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
let newFormat = DateFormatter()
newFormat.dateFormat = "dd MMM yyyy"
if let date = formatterGet.date(from: callDate) {
self.datesArr.append(newFormat.string(from: date))
}
}
}
for i in 0..<self.allContractsArr.count {
if let callDate = self.allContractsArr[i].revdat {
let formatterGet = DateFormatter()
formatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
let newFormat = DateFormatter()
newFormat.dateFormat = "dd MMM yyyy"
if let date = formatterGet.date(from: callDate) {
self.allContractsArr[i].revdat = newFormat.string(from: date)
}
}
}
self.allContractsArr = self.allContractsArr.sorted(by: { ($0.revdat)! > ($1.revdat)! })
self.contractsDict = Dictionary(grouping: self.allContractsArr, by: { ($0.revdat)! })
let newFormat = DateFormatter()
newFormat.dateFormat = "dd MMM yyyy"
self.datesArr = Array(Set(self.datesArr))
self.datesArr = self.datesArr.sorted(by: { newFormat.date(from: $0)! > newFormat.date(from: $1)! })
self.contractListCV.reloadData()
DispatchQueue.main.async {
self.activityBackView.isHidden = true
self.activity.isHidden = true
self.activity.stopAnimating()
self.design()
}
}
})
This is how I'm doing.
Getting the data in array format, converting them into Dictionary by grouping(by:) method, and then operating everything related to the collectionview upon those dictionary data.
My scenario, I am trying to load JSON data into UITableView. Here, the problem is my JSON having multiple array of multiple values. I need to get array keys as a Tableview section names and its all values load into relevant cell. I am using codable method for easy JSON data process. Now, how to do array key names (School, Office, etc,) into section and its values relevant cell.
My JSON
https://api.myjson.com/bins/r763z
My Codable
struct Root : Decodable {
let status : Bool
let data: ResultData
}
struct ResultData : Decodable {
let school, college, office, organisation, central : [Result]
}
struct Result : Decodable {
let id, name, date : String
let group : [String]
}
My JSON Decoder Code
func loadJSON(){
let urlPath = "https://api.myjson.com/bins/r763z"
let url = NSURL(string: urlPath)
let session = URLSession.shared
let task = session.dataTask(with: url! as URL) { data, response, error in
guard data != nil && error == nil else {
print(error!.localizedDescription)
return
}
do {
let decoder = JSONDecoder()
self.tableData = try decoder.decode(DivisionData.self, from: data!) // How to get section values and cell values and load table data
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch { print(error) }
}
task.resume()
}
Expected Output
To display the JSON in sections efficiently you have to decode the JSON into a struct with a title member
struct Root : Decodable {
let status : Bool
let sections : [Section]
private enum CodingKeys : String, CodingKey { case status, data }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(Bool.self, forKey: .status)
let data = try container.decode([String:[Result]].self, forKey: .data)
sections = data.compactMap{ return $0.value.isEmpty ? nil : Section(title: $0.key, result: $0.value) }
}
}
struct Section {
let title : String
let result : [Result]
}
struct Result : Decodable {
let id, name, date : String
let group : [String]
}
Declare a data source array
var sections = [Section]()
Assign the result to the array
do {
let decoder = try JSONDecoder().decode(Root.self, from: data!)
let status = decoder.status
if status == true {
sections = decoder.sections
DispatchQueue.main.async {
self.tableView.reloadData()
}
} else {
}
} catch { print(error) }
The relevant table view data source methods are
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].result.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].title
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
let item = sections[indexPath.section].result[indexPath.row]
// Update the UI
}
Side note: Name your structs with more meaningful names. For example an array is supposed to be named with something in plural form (like in my previous suggestion)
Just use the different arrays for the different sections.
var tableData: ResultData?
override func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let tableData = tableData else { return 0 }
switch section {
case 0:
return tableData.school.count
case 1:
return tableData.college.count
case 2:
return tableData.office.count
case 3:
return tableData.organisation.count
case 4:
return tableData.central.count
default:
return 0
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "School"
case 1:
return "College"
case 2:
return "Office"
case 3:
return "Organisation"
case 4:
return "Central"
default:
return nil
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
// Get item
var item: Result?
switch section {
case 0:
item = tableData?.school[indexPath.row]
case 1:
item = tableData?.college[indexPath.row]
case 2:
item = tableData?.office[indexPath.row]
case 3:
item = tableData?.organisation[indexPath.row]
case 4:
item = tableData?.central[indexPath.row]
default:
break
}
if let item = item {
// Configure the cell...
}
return cell
}
To fetch your data, you need to use a URLSession like that:
func fetchData() {
guard let url = URL(string: "https://api.myjson.com/bins/r763z") else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("An error occurred: \(error)")
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 200 {
let decoder = JSONDecoder()
do {
let json = try decoder.decode(Root.self, from: data)
tableData = json.data
// Reload table view
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Decoding error: \(error)")
}
}
}
task.resume()
}
My entire table view is being written programmatically and the data is coming from JSON. I am trying to group the cells by the customer the code seems to be correct but no sections are showing up at all.
Here is the code:
Portfolios.swift
import UIKit
struct Portfolios: Codable {
let customer, serial, rma, model: String
let manufacturer: String
}
PortfolioController.swift
import UIKit
class PortfolioController: UITableViewController {
var portfolios = [Portfolios]()
var portfoliosDic = [String:[Portfolios]]()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
view.backgroundColor = UIColor.blue
navigationItem.title = "Customer"
fetchJSON()
}
func fetchJSON(){
let urlString = "https://www.example.com/example/example.php"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, _, error) in
DispatchQueue.main.async {
if let error = error {
print("Failed to fetch data from url", error)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try JSONDecoder().decode([Portfolios].self, from: data)
self.portfoliosDic = Dictionary(grouping: res, by: { $0.customer})
DispatchQueue.main.async {
self.tableView.reloadData()
}
self.portfolios = try decoder.decode([Portfolios].self, from: data)
self.tableView.reloadData()
} catch let jsonError {
print("Failed to decode json", jsonError)
}
}
}.resume()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return portfoliosDic.keys.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let keys = Array(portfoliosDic.keys)
let item = portfoliosDic[keys[section]]!
return item.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
let keys = Array(portfoliosDic.keys)
let arr = portfoliosDic[keys[indexPath.section]]!
let customer = arr[indexPath.row]
let titleStr = [customer.serial, customer.manufacturer, customer.model].compactMap { $0 }.joined(separator: " - ")
//cell.textLabel?.text = titleStr
print(titleStr)
// Get references to labels of cell
cell.textLabel!.text = customer.serial
return cell
}
}
UPDATE:
Because it is a UIViewController Xcode told me to remove the override func
and I added #IBOutlet weak var tableView: UITableView!
(The end results is an empty table for some reason)
Using a UITableViewController instead:
import UIKit
class CustomerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var sections = [Section]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
navigationController?.navigationBar.prefersLargeTitles = true
fetchJSON()
}
func fetchJSON(){
let urlString = "https://www.example.com/example/example.php"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, _, error) in
DispatchQueue.main.async {
if let error = error {
print("Failed to fetch data from url", error)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode([Portfolios].self, from: data)
let grouped = Dictionary(grouping: res, by: { $0.customer })
let keys = grouped.keys.sorted()
self.sections = keys.map({Section(name: $0, items: grouped[$0]!)})
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Failed to decode json", error)
}
}
}.resume()
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
return section.items.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].name
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
let section = sections[indexPath.section]
let item = section.items[indexPath.row]
let titleStr = "\(item.serial) - \(item.manufacturer) - \(item.model)"
cell.textLabel!.text = titleStr
return cell
}
}
First of all why do you decode the JSON twice?
No sections are displayed because the method titleForHeaderInSection is not implemented.
The code is not reliable anyway because the order of the sections is not guaranteed. I recommend to create another struct for the sections.
struct Section {
let name : String
let items : [Portfolios]
}
struct Portfolios: Decodable {
let customer, serial, rma, model: String
let manufacturer: String
}
Delete portfolios and portfoliosDic and declare the data source array
var sections = [Section]()
Group the JSON, sort the keys and map the dictionaries to Section instances
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode([Portfolios].self, from: data)
let grouped = Dictionary(grouping: res, by: { $0.customer })
let keys = grouped.keys.sorted()
self.sections = keys.map({Section(name: $0, items: grouped[$0]!)})
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Failed to decode json", error)
}
The table view datasource and delegate methods are
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
return section.items.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].name
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
let section = sections[indexPath.section]
let item = section.items[indexPath.row]
let titleStr = "\(item.serial) - \(item.manufacturer) - \(item.model)"
cell.textLabel!.text = titleStr
return cell
}
Note:
Always dequeue cells in cellForRowAt
Getting a JSON object from a rest web service I get the data from the object and I want to show it in a tableview.
class TableViewController1: UITableViewController {
var nomProduit = ["ok"]
var prixProduit = [""]
var vt1 : String?
var vt2 : String?
var i : Int!
var compteur1:Int!
var resultat1:NSArray?
var x : AnyObject?
override func viewDidLoad() {
super.viewDidLoad()
// \(detectionString)
let str:String = "http://vps43623.ovh.net/yamoinscher/api/products/6194005492077"
let url = NSURL(string: str)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.MutableContainers)
self.resultat1 = jsonResult["meme_categorie"] as? NSArray
self.compteur1 = self.resultat1!.count
print(self.compteur1!)
//self.value = (compteur1 as? Int)!
for self.i=0 ; self.i < self.compteur1! ; self.i = self.i+1 {
if let aStatus = self.resultat1![self.i] as? NSDictionary{
self.vt1 = aStatus["libelle_prod"]! as? String
self.nomProduit.append(self.vt1!)
self.vt2 = aStatus["prix"]! as? String
self.prixProduit.append(self.vt2!)
//print(self.nomProduit[self.i])
}
}
} catch {
print("JSON serialization failed")
}
}
}
task.resume()
}
Then My problem is that this array stays nil:
self.prixProduit.append(self.vt2!)
here is the rest of my code
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 17
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! customCell1
// cell.PrixSim.text = nomProduit[indexPath.row]
print(self.nomProduit[0])
return cell
}
First of all use a custom struct for the category objects, it makes things so much easier.
At the beginning of TableViewController1
class TableViewController1: UITableViewController {
declare this struct
struct Produit {
var id : String
var prix : String
var title : String
}
and a data source array (forget all your other properties / variables)
var produits = [Produit]()
In viewDidLoad get the data, populate the data source array and reload the table view on the main thread.
This code uses Swift native collection types
override func viewDidLoad() {
super.viewDidLoad()
// \(detectionString)
let str = "http://vps43623.ovh.net/yamoinscher/api/products/6194005492077"
let url = NSURL(string: str)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(urlContent, options: [])
if let jsonResult = jsonObject as? [String:AnyObject] {
if let memeCategorie = jsonResult["meme_categorie"] as? [[String:String]] {
for categorie in memeCategorie {
if let prix = categorie["prix"], title = categorie["libelle_prod"], id = categorie["id"] {
self.produits.append(Produit(id: id, prix: prix, title: title))
}
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
}
}
} catch {
print("JSON serialization failed", error)
}
} else if let connectionError = error {
print("connection error", connectionError)
}
}
task.resume()
}
In numberOfRowsInSection return the actual number of items rather than a hard-coded number.
You can omit numberOfSectionsInTableView since the default value is 1.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return produits.count
}
In cellForRowAtIndexPath get the item by index path and assign the values to your labels (or whatever). For now the values are just printed out.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! customCell1
let produit = produits[indexPath.row]
print(produit.id, produit.title, produit.prix)
return cell
}
}