Ajouter des Section dans un UITableView


#1

Bonjour, j’aimerai ajouter des section dans mon UITableView.

Je m’explique je décode les données de fichier JSON elle arrive bien dans mon tableview mais j’aimerai mettre toutes les données du même jour dans une section.

Comme le montre les images, toutes les données son bien classer par date et heure ( la date et l’heure son formater par une fonction)

IMG_0108

J’aimerai donc que la section reprenne "Aujourd’hui " et en dessous toutes les heures du JSON et ainsi pour tout les jours compris dans le JSON

Voici le code du controller afin d’être précis.

import UIKit
import Alamofire
import MapKit

class WeatherProController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource,UITableViewDelegate  {
    
    private let refreshControl = UIRefreshControl()
    
    var datas = [WeatherProData]()
    var locManager = CLLocationManager()
    var currentLocation: CLLocation!
    
    var timer = Timer()
    var jour = UIColor(red: 0, green: 191 / 255, blue: 1, alpha: 1)
    var nuit = UIColor(red: 51 / 255, green: 116 / 255, blue: 255 / 255, alpha: 1)
    
    let didBecomeActiveNotificationName = UIApplication.didBecomeActiveNotification
    
    let identifiantCell = "dataProCell"
    let identifiantSegue = "versDetailDonneePro"
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var menuButton: UIBarButtonItem!
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        locManager.requestAlwaysAuthorization()
        NotificationCenter.default.addObserver(self, selector: #selector(scheduleTimer), name: didBecomeActiveNotificationName, object: nil)
        changeBackground()
        data()
        
        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            tableView.refreshControl = refreshControl
        } else {
            tableView.addSubview(refreshControl)
        }
        // Configure Refresh Control
        refreshControl.addTarget(self, action: #selector(refreshWeatherData(_:)), for: .valueChanged)
        refreshControl.tintColor = UIColor.white
        let attributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
        refreshControl.attributedTitle = NSAttributedString(string: "Refreshing please wait", attributes: attributes)

    }
    
    @objc private func refreshWeatherData(_ sender: Any) {
        fetchWeatherData()
    }
    
    private func setupActivityIndicatorView() {
        activityIndicatorView.startAnimating()
    }
    
    private func fetchWeatherData() {
        data()
        self.refreshControl.endRefreshing()
//        self.activityIndicatorView.stopAnimating()
    }
    
    @objc func scheduleTimer() {
        // schedule the timer
        timer = Timer(fireAt: Calendar.current.nextDate(after: Date(), matching: DateComponents(hour: 6..<21 ~= Date().hour ? 21 : 6), matchingPolicy: .nextTime)!, interval: 0, target: self, selector: #selector(changeBackground), userInfo: nil, repeats: false)
        print(timer.fireDate)
        //        RunLoop.main.add(timer, forMode: .RunLoop.Mode.common)
        print("new background chenge scheduled at:", timer.fireDate.description(with: .current))
    }
    
    @objc func changeBackground(){
        // check if day or night shift
        self.view.backgroundColor =  6..<21 ~= Date().hour ? jour : nuit
        // schedule the timer
        scheduleTimer()
    }

    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return datas.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: identifiantCell) as? WeatherProCell {
            let data = datas[indexPath.row]
            cell.creerCell(data)
            return cell
        }
        return UITableViewCell()
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? WeatherProCell {
            cell.textIsHidden.isHidden = !cell.textIsHidden.isHidden
            cell.textIsHidden1.isHidden = !cell.textIsHidden1.isHidden
            cell.textIsHidden2.isHidden = !cell.textIsHidden2.isHidden
            cell.textIsHidden3.isHidden = !cell.textIsHidden3.isHidden
            cell.textIsHidden4.isHidden = !cell.textIsHidden4.isHidden
            cell.textIsHidden5.isHidden = !cell.textIsHidden5.isHidden
            cell.textIsHidden6.isHidden = !cell.textIsHidden6.isHidden
            cell.textIsHidden7.isHidden = !cell.textIsHidden7.isHidden
            cell.textIsHidden8.isHidden = !cell.textIsHidden8.isHidden
            cell.textIsHidden9.isHidden = !cell.textIsHidden9.isHidden
            cell.cloud.isHidden = !cell.cloud.isHidden
            cell.rTemp.isHidden = !cell.rTemp.isHidden
            cell.cloudBase.isHidden = !cell.cloudBase.isHidden
            cell.dewp.isHidden = !cell.dewp.isHidden
            cell.press.isHidden = !cell.press.isHidden
            cell.pressIcon.isHidden = !cell.pressIcon.isHidden
            cell.hydro.isHidden = !cell.hydro.isHidden
            cell.hydroIcon.isHidden = !cell.hydroIcon.isHidden
            cell.vent.isHidden = !cell.vent.isHidden
            cell.ventIcon.isHidden = !cell.ventIcon.isHidden
            cell.rainIcon.isHidden = !cell.rainIcon.isHidden
            cell.rain.isHidden = !cell.rain.isHidden
            cell.iso0.isHidden = !cell.iso0.isHidden
            cell.freezeRain.isHidden = !cell.freezeRain.isHidden
            cell.noSnow.isHidden = !cell.noSnow.isHidden
            cell.snowUp.isHidden = !cell.snowUp.isHidden
            cell.visibility.isHidden = !cell.visibility.isHidden
            cell.snowProb.isHidden = !cell.snowProb.isHidden
            
            tableView.beginUpdates()
            tableView.endUpdates()
            tableView.deselectRow(at: indexPath, animated: true)
        }
    }
    
    func data() {
        if ( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
            CLLocationManager.authorizationStatus() == .authorizedAlways) {
            currentLocation = locManager.location
        }
        
        var headers: HTTPHeaders = [
            "Content-Type": "application/json"
        ]
        
        let user = loginWeatherPro
        let password = motDePasseWeatherPro
        
        if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
            headers[authorizationHeader.key] = authorizationHeader.value
        }
        
        let now = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone.init(abbreviation: "UTC")
        formatter.locale = Locale(identifier: "en_US_POSIX")
        print(formatter.string(from: now))
        let days = Calendar.current.date(byAdding: .day, value: 15, to: now)
        
        let urlB = urlDeBaseWeatherPro
        let locate = "locatedAt=\(currentLocation.coordinate.longitude),\(currentLocation.coordinate.latitude)"
        let period = "&validPeriod=PT0S"
        let validFrom = "&validFrom=\(formatter.string(from: now))"
        let validUntil = "&validUntil=\(formatter.string(from: days!))"
        let fields = "&fields=" + fieldsParameter
        let url = urlB + locate + period + validFrom + validUntil + fields
        print(url)
        
        Alamofire.request(url, headers:headers).responseJSON{ response in
            if let JSON = response.result.value as? [String: AnyObject] {
                if let forecast = JSON ["forecasts"] as? NSArray {
                    for element in forecast {
                        if let dict = element as? [String: AnyObject],
                            let dates = dict ["validFrom"] as? String ,
                            let weatherCode = dict ["weatherCode"] as? Int ,
                            let weatherCodeString = weatherCodesTab[weatherCode],
                            let temp = dict ["airTemperatureInCelsius"] as? Double ,
                            let cloud = dict ["effectiveCloudCoverInPercent"] as? Double ,
                            let rtemp = dict ["feelsLikeTemperatureInCelsius"] as? Double ,
                            let cloudBase = dict ["cloudBaseHeightInMeter"] as? Double ,
                            let dewp = dict ["dewPointTemperatureInCelsius"] as? Double ,
                            let press = dict ["airPressureAtSeaLevelInHectoPascal"] as? Double ,
                            let hydro = dict ["relativeHumidityInPercent"] as? Double ,
                            let vent = dict ["windSpeedInKilometerPerHour"] as? Double ,
                            let rain = dict ["precipitationProbabilityInPercent"] as? Double ,
                            let iso0 = dict ["freezingLevelHeightInMeter"] as? Double ,
                            let freezeRain = dict ["freezingRainProbabilityInPercent"] as? Double ,
                            let noSnow = dict ["noSnowPossibleBelowHeightInMeter"] as? Double ,
                            let snowUp = dict ["snowCertainAboveHeightInMeter"] as? Double ,
                            let visibility = dict ["visibilityInMeter"] as? Double ,
                            let snowProd = dict ["snowfallProbabilityInPercent"] as? Double {
                            
                            
                            self.datas.append(WeatherProData(date: (DateHelper.obtenir.jourDeLaSemaineWeather(dates)!) + " " + DateHelper.obtenir.dateWeatherPro(dates)! + " à " + (DateHelper.obtenir.heures(dates)!), weatherCode: weatherCodeString, temp: temp, cloud: cloud, rtemp: rtemp, cloudBase: cloudBase, dewp: dewp, press: press, hydro: hydro, vent: vent, rain: rain, iso0: iso0, freezeRain: freezeRain, noSnow: noSnow, snowUp: snowUp, visibility: visibility, snowProb: snowProd))
                            
//                            print(weatherCodeString)
                            
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    }
}

Pourriez-Vous m’indiquer comment faire car après 2 semaines à avoir chercher dans tout les recoins du web je n’y arrive pas comme je le veux.

Merci à vous


#2

Hello,

Il te suffit juste d’ajouter les fonctions te permettant de créer le header de ta table.

Voila un exemple pour te lancer
https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-section-header-to-a-table-view

:v:t3:


#3

Je crois que je n’ai pas été compris.

Ce que j’aimerai faire c’est que chaque jours soit dans une section et que dans chaque section on y retrouve les données météo de chaque heure.

Hello,

Il te suffit juste d’ajouter les fonctions te permettant de créer le header de ta table.

Voila un exemple pour te lancer
https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-section-header-to-a-table-view

Merci, mais cela ne me donne qu’une section principale.


#4

Hello,

L’exemple que t’a fourni @s0ta est correct, mais ne fais pas exactement ce que tu souhaites et c’est normal.
Regarde la signature de la méthode :

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section)"
}

La méthode attends un numéro de section.
Il faut donc que tu découpe des données JSON en section, et au lieu d’avoir un seul tableau de data tu en aura plusieurs.

Je te renvoie par exemple vers cette discussion qui, il me semble, répond a tes questions.


#5

Merci pour l’info,

J’ai regardé un peu mais cela me semble compliqué avec mon code actuel :unamused:

Je nage dans la semoule pour ces section :weary:


#6

Et bien modifie ton code pour que cela fonctionne :slight_smile:


#7

Merci :blush:

Mais le fait est que je ne voie pas comment modifier le décryptage du JSON en plusieurs secteur.

Je désespère de mettre cette fonction de secteur dans mon appli mais je continue à chercher.


#8

Eh bien, ne le fait pas … Ne touche surtout pas au décryptage du JSON !

En regardant ton code, je vois que tu as toutes les informations stockées sous forme d’objets WeatherProData, dans le tableau datas.

Il suffit de parcourir ce tableau pour trier les informations au format voulu. J’ai déjà expliqué comme traiter un problème similaire, quelque part sur le forum, à propos d’une application sportive, mais je ne sais plus où.

L’idée c’est de lire une première fois tous les éléments du tableau datas pour noter le nombre de dates différentes. Et de créer autant de tableaux qu’il y a de jours. Puis parcourir à nouveau le tableau datas pour copier chaque objet WeatherProData dans le tableau correspondant à son jour.

Ensuite c’est facile de gérer les sections, chaque tableau correspondant à sa propre section.

C’est presque la même logique que ton application, avec une étape supplémentaire de formatage des données, APRES la lecture des données brutes du JSON.


#9

Par ici je crois : Calculs dans un Array et TableView


#10

Non, gaveline. C’est un autre post, plus ancien, en réponse à une autre problématique de jean-charles, sur la même application sportive. Enfin je crois, je répond a tellement de personnes sur différents forums que je me mélange parfois les pédales. Je chercherais à tête reposée.


#11

Merci à vous

@Draken je cherche dans tes messages mais comme tu es très actif c’est pas évident à trouver :wink:

J’essaie de faire avancer le schmilblik mais comme je suis novice …


#12

En fait c’est ce topic là : TableView Sections avec des dates?


#13

Merci à tous.

Après plusieurs essais, j’arrive à appliquer ce que j’ai lu sur un nouveau projet, mais je n’arrive pas à l’appliquer dans mon projet existant avec le JSON

Dans mon projet actuel les sections son reprise 15x avec a chaque fois toutes les cell en dessous


#14

Hello @JefNewTech

Fais-nous voir ton code (le nouveau et celui sur le projet existant), qu’on y jette un oeil :slight_smile:

Bonne soirée,

Alexandre


#15

Voici mon code qui ne fonctionne pas comme je veux. :scream:

import UIKit
import Alamofire
import MapKit

class WeatherProController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource,UITableViewDelegate  {
    
    private let refreshControl = UIRefreshControl()
    
    var datas = [WeatherProData]()
    var locManager = CLLocationManager()
    var currentLocation: CLLocation!
    
    var timer = Timer()
    var jour = UIColor(red: 0, green: 191 / 255, blue: 1, alpha: 1)
    var nuit = UIColor(red: 51 / 255, green: 116 / 255, blue: 255 / 255, alpha: 1)
    
    let didBecomeActiveNotificationName = UIApplication.didBecomeActiveNotification
    
    let identifiantCell = "dataProCell"
    let identifiantSegue = "versDetailDonneePro"
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var menuButton: UIBarButtonItem!
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        locManager.requestAlwaysAuthorization()
        NotificationCenter.default.addObserver(self, selector: #selector(scheduleTimer), name: didBecomeActiveNotificationName, object: nil)
        changeBackground()
        data()
        
        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            tableView.refreshControl = refreshControl
        } else {
            tableView.addSubview(refreshControl)
        }
        // Configure Refresh Control
        refreshControl.addTarget(self, action: #selector(refreshWeatherData(_:)), for: .valueChanged)
        refreshControl.tintColor = UIColor.white
        let attributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
        refreshControl.attributedTitle = NSAttributedString(string: "Refreshing please wait", attributes: attributes)

    }
    
    @objc private func refreshWeatherData(_ sender: Any) {
        fetchWeatherData()
    }
    
    private func setupActivityIndicatorView() {
        activityIndicatorView.startAnimating()
    }
    
    private func fetchWeatherData() {
        data()
        self.refreshControl.endRefreshing()
//        self.activityIndicatorView.stopAnimating()
    }
    
    @objc func scheduleTimer() {
        // schedule the timer
        timer = Timer(fireAt: Calendar.current.nextDate(after: Date(), matching: DateComponents(hour: 6..<21 ~= Date().hour ? 21 : 6), matchingPolicy: .nextTime)!, interval: 0, target: self, selector: #selector(changeBackground), userInfo: nil, repeats: false)
        print(timer.fireDate)
        //        RunLoop.main.add(timer, forMode: .RunLoop.Mode.common)
        print("new background chenge scheduled at:", timer.fireDate.description(with: .current))
    }
    
    @objc func changeBackground(){
        // check if day or night shift
        self.view.backgroundColor =  6..<21 ~= Date().hour ? jour : nuit
        // schedule the timer
        scheduleTimer()
    }

    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return datas.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: identifiantCell) as? WeatherProCell {
            let data = datas[indexPath.row]
            cell.creerCell(data)
            return cell
        }
        return UITableViewCell()
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? WeatherProCell {
            cell.textIsHidden.isHidden = !cell.textIsHidden.isHidden
            cell.textIsHidden1.isHidden = !cell.textIsHidden1.isHidden
            cell.textIsHidden2.isHidden = !cell.textIsHidden2.isHidden
            cell.textIsHidden3.isHidden = !cell.textIsHidden3.isHidden
            cell.textIsHidden4.isHidden = !cell.textIsHidden4.isHidden
            cell.textIsHidden5.isHidden = !cell.textIsHidden5.isHidden
            cell.textIsHidden6.isHidden = !cell.textIsHidden6.isHidden
            cell.textIsHidden7.isHidden = !cell.textIsHidden7.isHidden
            cell.textIsHidden8.isHidden = !cell.textIsHidden8.isHidden
            cell.textIsHidden9.isHidden = !cell.textIsHidden9.isHidden
            cell.cloud.isHidden = !cell.cloud.isHidden
            cell.rTemp.isHidden = !cell.rTemp.isHidden
            cell.cloudBase.isHidden = !cell.cloudBase.isHidden
            cell.dewp.isHidden = !cell.dewp.isHidden
            cell.press.isHidden = !cell.press.isHidden
            cell.pressIcon.isHidden = !cell.pressIcon.isHidden
            cell.hydro.isHidden = !cell.hydro.isHidden
            cell.hydroIcon.isHidden = !cell.hydroIcon.isHidden
            cell.vent.isHidden = !cell.vent.isHidden
            cell.ventIcon.isHidden = !cell.ventIcon.isHidden
            cell.rainIcon.isHidden = !cell.rainIcon.isHidden
            cell.rain.isHidden = !cell.rain.isHidden
            cell.iso0.isHidden = !cell.iso0.isHidden
            cell.freezeRain.isHidden = !cell.freezeRain.isHidden
            cell.noSnow.isHidden = !cell.noSnow.isHidden
            cell.snowUp.isHidden = !cell.snowUp.isHidden
            cell.visibility.isHidden = !cell.visibility.isHidden
            cell.snowProb.isHidden = !cell.snowProb.isHidden
            
            tableView.beginUpdates()
            tableView.endUpdates()
            tableView.deselectRow(at: indexPath, animated: true)
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return datas.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return datas[section].date
    }
    
    func data() {
        if ( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
            CLLocationManager.authorizationStatus() == .authorizedAlways) {
            currentLocation = locManager.location
        }
        
        var headers: HTTPHeaders = [
            "Content-Type": "application/json"
        ]
        
        let user = loginWeatherPro
        let password = motDePasseWeatherPro
        
        if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
            headers[authorizationHeader.key] = authorizationHeader.value
        }
        
        let now = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone.init(abbreviation: "UTC")
        formatter.locale = Locale(identifier: "en_US_POSIX")
        print(formatter.string(from: now))
        let days = Calendar.current.date(byAdding: .day, value: 15, to: now)
        
        let urlB = urlDeBaseWeatherPro
        let locate = "locatedAt=\(currentLocation.coordinate.longitude),\(currentLocation.coordinate.latitude)"
        let period = "&validPeriod=PT0S"
        let validFrom = "&validFrom=\(formatter.string(from: now))"
        let validUntil = "&validUntil=\(formatter.string(from: days!))"
        let fields = "&fields=" + fieldsParameter
        let url = urlB + locate + period + validFrom + validUntil + fields
        print(url)
        
        Alamofire.request(url, headers:headers).responseJSON{ response in
            if let JSON = response.result.value as? [String: AnyObject] {
                if let forecast = JSON ["forecasts"] as? NSArray {
                    for element in forecast {
                        if let dict = element as? [String: AnyObject],
                            let dates = dict ["validFrom"] as? String ,
                            let weatherCode = dict ["weatherCode"] as? Int ,
                            let weatherCodeString = weatherCodesTab[weatherCode],
                            let temp = dict ["airTemperatureInCelsius"] as? Double ,
                            let cloud = dict ["effectiveCloudCoverInPercent"] as? Double ,
                            let rtemp = dict ["feelsLikeTemperatureInCelsius"] as? Double ,
                            let cloudBase = dict ["cloudBaseHeightInMeter"] as? Double ,
                            let dewp = dict ["dewPointTemperatureInCelsius"] as? Double ,
                            let press = dict ["airPressureAtSeaLevelInHectoPascal"] as? Double ,
                            let hydro = dict ["relativeHumidityInPercent"] as? Double ,
                            let vent = dict ["windSpeedInKilometerPerHour"] as? Double ,
                            let rain = dict ["precipitationProbabilityInPercent"] as? Double ,
                            let iso0 = dict ["freezingLevelHeightInMeter"] as? Double ,
                            let freezeRain = dict ["freezingRainProbabilityInPercent"] as? Double ,
                            let noSnow = dict ["noSnowPossibleBelowHeightInMeter"] as? Double ,
                            let snowUp = dict ["snowCertainAboveHeightInMeter"] as? Double ,
                            let visibility = dict ["visibilityInMeter"] as? Double ,
                            let snowProd = dict ["snowfallProbabilityInPercent"] as? Double {
                            
                            
                            self.datas.append(WeatherProData(date: (DateHelper.obtenir.jourDeLaSemaineWeather(dates)!) + " " + DateHelper.obtenir.dateWeatherPro(dates)! + " à " + (DateHelper.obtenir.heures(dates)!), weatherCode: weatherCodeString, temp: temp, cloud: cloud, rtemp: rtemp, cloudBase: cloudBase, dewp: dewp, press: press, hydro: hydro, vent: vent, rain: rain, iso0: iso0, freezeRain: freezeRain, noSnow: noSnow, snowUp: snowUp, visibility: visibility, snowProb: snowProd))
                            
//                            print(weatherCodeString)
                            
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    }
}

#16

En effet, c’est tout à fait normal que cela ne fonctionne pas comme tu veux :

func numberOfSections(in tableView: UITableView) -> Int {
    return datas.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return datas.count
}

Tu définis le nombre de section de la même manière que tu définis les données dans les sections, cela ne me semble pas logique.

Quand je regarde la structure des objets dans le tableau “datas”, je vois ceci :

(DateHelper.obtenir.jourDeLaSemaineWeather(dates)!) + " " + DateHelper.obtenir.dateWeatherPro(dates)! + " à " + (DateHelper.obtenir.heures(dates)!)`

Je suppose que tout cela retourne une date (par exemple: lundi 12 décembre 13:05:56), peu importe le format.
Si tu veux ensuite grouper tes datas en fonction de leurs dates, tu vas devoir faire un tri.
Dans un premier temps, tu récupères tes données depuis Alamofire, aucun soucis. Ensuite, si j’étais toi, je parcourrai toutes les données que tu as récupérées via ta requêtes, et je les grouperais dans des tableaux distincts, en fonction de leurs dates.

Voici un exemple (je simplifie la structure pour une question de lisibilité) :

Imaginons que tes données de météo ne comporte qu’une date et un temps (nuageux, soleil, etc) et que tu as un tableau avec des données de ce type (ce que tu as récupéré avec Alamofire), voici comment tu pourrais faire pour classer toutes ces données par date :

for data in datas {

    // Si déjà au moins un élément dans le tableau des données groupées
    if datasGroupees.count > 0 {
        // Parcourt des éléments déjà présents dans le tableau des données groupées
        for (index, dataGroupee) in datasGroupees.enumerated() {
            
            // Par défaut, aucune section dans laquelle on doit ajouter l'élément, donc index -1
            var indexSection:Int = -1
            
            // Si le premier élément du sous tableau a la même date que l'élément que l'on souhaite ajouter, alors, la section existe déjà, on doit ajouter la données à cette section
            if dataGroupee[0].date == data.date {
                // Donc, on retient son index
                indexSection = index
                break
            }
            
            // Si aucune section avec la date du nouvel élement
            if indexSection == -1 {
                // Ajout de la nouvelle donnée comme si c'était un premier élément
                datasGroupees.append([data])
            }
            // Sinon, une section avec la même date existe déjà
            else {
                // Ajout de la donnée dans la section que l'on a trouvé tout à l'heure
                datasGroupees[indexSection].append(data)
            }
        }
        
    }
    // Sinon, premier élément
    else {
        datasGroupees.append([data])
    }

}

Ensuite, tu pourrais connaitre le nombre de sections en faisant :

datasGroupees.count

Et le nombre d’éléments dans une section en faisant :

datasGroupees[indexDeLaSectionVoulue].count
// indexDeLaSectionVoulue étant un numéro de section

Je me suis posé la même question il y a quelques temps (voir le lien du post de Draken), donc si je peux aider maintenant que j’ai compris une manière de faire, hésite pas ! :slight_smile:

Bonne soirée,

Alexandre


#17

Merci je vais essayer d’appliquer ce que tu me propose.


#18

Bonjour et meilleur vœux à tous, je reviens vers vous car je n’ arrive pas à mettre en pratique vos exemple dans mon fichier.

Je vous demande donc encore un peut d’aide.

Merci


#19

Hello @JefNewTech,

Peux-tu nous montrer le code que tu as essayé de faire ?
Ainsi, nous pourrons regarder et rectifier ensemble ce que tu as essayé de faire et ce qui ne va pas.

Bonne journée,

Alexandre


#20

J’ai mis en suspend le projet original pour essayer d’y arriver sur un autre projet test mais rien n’y fait
J’ai fait quelque chose de rapide

import UIKit
import Alamofire

struct WeatherProData {
    
    let date: String // must be `Date` for smart grouping
//    let weatherCode: String
//    let temp: Double
//    let cloud: Doublea
//    let rTemp: Double
//    let cloudBase: Double
//    let dewp: Double
//    let press: Double
//    let hydro: Double
//    let vent: Double
//    let rain: Double
//    let iso0: Double
//    let freezeRain: Double
//    let noSnow: Double
//    let snowUp: Double
//    let visibility: Double
//    let snowProb: Double
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    
    var data = [WeatherProData]()
    var sections = [Date]()
    var dataT = [Date:[String]]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        
        let date = Date()
        let value = "Test"
        
        if !sections.contains(date) {
            sections.append(date)
            dataT[date] = [String]()
        }
        
        dataT[date]?.append(value)
        
        var headers : HTTPHeaders = ["Content-Type":"application.json"]
        
        //        Ajout lofin et mot de passe pour la connection à weather pro
        let user = loginWeatherPro
        let password = motDePasseWeatherPro
        
        //        Ajout de l'autorisation de connection
        if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
            headers[authorizationHeader.key] = authorizationHeader.value
        }
        
        //        formattage de l'heure
        let now = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone.init(abbreviation: "UTC")
        formatter.locale = Locale(identifier: "en_US_POSIX")
        print(formatter.string(from: now))
        let days = Calendar.current.date(byAdding: .day, value: 1, to: now)
        
        //        preparation de l'url de base
        let urlB = urlDeBaseWeatherPro
        let locate = "locatedAt=3.284752,50.644164"
        let period = "&validPeriod=PT0S"
        let validFrom = "&validFrom=\(formatter.string(from: now))"
        let validUntil = "&validUntil=\(formatter.string(from: days!))"
        let fields = "&fields=" + fieldsParameter
        let url = urlB + locate + period + validFrom + validUntil + fields
        
        Alamofire.request(url, headers:headers).responseJSON { response in
            if let JSON = response.result.value as? [String: AnyObject] {
                if let forecast = JSON ["forecasts"] as? NSArray {
                    for element in forecast {
                        if let dict = element as? [String: AnyObject],
                            let dates = dict ["validFrom"] as? String {
                            self.data.append(WeatherProData(date: dates))
                            print(dates)
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataT.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "test"
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let datas = data[indexPath.row]
        cell.textLabel?.text = datas.date
        return cell
    }
}