Aller au contenu


Photo

création et remplissage tableView (code) sans storyBoard


  • Please log in to reply
53 réponses à ce sujet

#1 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 06 février 2017 - 12:24

Bonjour,

 

 

j'aimerais savoir comment implémenter une tableView (code), sans utilisé le storyBoard et dans un viewController ?

 

Le début est correcte mais c'est pour l'ajout des données que je sèche :

let tableView:UITableView = UITableView(frame: CGRect(x:130, y: 30, width:200, height:400))
tableView.reloadData()
tableView.backgroundColor =  UIColor(red: 85/255, green: 175/255, blue: 101/255, alpha: 1.0)
        
// compte le nombre d'éléments de mon tableau
tableView.numberOfRows(inSection:connexion.arrayData.count)

/ puis ma boucle pour ajouter mes données :
for data in connexion.arrayData
{
  let cell = tableView.dequeueReusableCell( withIdentifier:??, for:??)
  cell.myLabel.text = data
}
self.view.addSubview(tableView)

// avec ce code ma tableView s'affiche mais je ne sais pas comment remplir les champs "??"

En fait, j'aimerais pouvoir "mapper" automatiquement les colonnes et les lignes de ma requête en base, sur ma tableView.

Car mon tableau "data" contient les champs de mes tables, exemple :

id:1

name: nom

description: description

etc

 

Sans forcément les mêmes champs 

 

En somme remplir un tableau automatiquement en respectant colonnes/lignes... (mais avec la possibilité de ne pas afficher certaines lignes (exemple les id)

 

Merci à toutes et tous :)



#2 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 février 2017 - 12:41

j'aimerais savoir comment implémenter une tableView (code), sans utilisé le storyBoard et dans un viewController ?

 

Mais pourquoi ? Tu veux aussi poser et gonfler les pneus sur les roues avant chaque fois que tu conduises ta bagnole ?

 

Le début est correcte mais c'est pour l'ajout des données que je sèche :

let tableView:UITableView = UITableView(frame: CGRect(x:130, y: 30, width:200, height:400))
tableView.reloadData()
tableView.backgroundColor =  UIColor(red: 85/255, green: 175/255, blue: 101/255, alpha: 1.0)
        
// compte le nombre d'éléments de mon tableau
tableView.numberOfRows(inSection:connexion.arrayData.count)

/ puis ma boucle pour ajouter mes données :
for data in connexion.arrayData
{
  let cell = tableView.dequeueReusableCell( withIdentifier:??, for:??)
  cell.myLabel.text = data
}


// avec ce code ma tableView s'affiche mais je ne sais pas comment remplir les champs "??"

 

Le début n'est pas du tout correct.

 

1. Tu n'as pas considéré les contraintes pour maintenir la position à la rotation

 

2. Le seul moyen de remplir une tableView, c'est par son delegate et son dataSource

 

2. tu appelles reloadData avent que tu as connecté la tableView à son delegate et son dataSource

 

3. tu n'as pas implémenté ni le delegate ni le dataSource

 

4. les méthodes que tu as appelé sur la tableView sont les méthodes que l'on ne doive pas appeler, elles devraient être appelé seulement par le tableView lorsque elle en a besoin.

 

En fait, j'aimerais pouvoir "mapper" automatiquement les colonnes et les lignes de ma requête en base, sur ma tableView.

 

En somme remplir un tableau automatiquement en respectant colonnes/lignes... (mais avec la possibilité de ne pas afficher certaines lignes (exemple les id)

 

Les tableViews ne comprennent pas les colonnes. Il faut considérer construire les cellules avec multiples parties ou d'utiliser une UICollectionView.

 

Mais je répète - pourquoi ne pas utiliser un storyboard ?


  • toolsDev aime ceci

#3 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 06 février 2017 - 13:10

si je voulais faire ainsi, c'est pour ne pas avoir ma tableView sur ma vue.

donc si je la place sur le storyboard je vais avoir un empilement d'objets, voilà tout...

 

la tableView doit être positionné à un certain endroit au clique d'un bouton. Alors quoi de plus pratique que je la construire à la volé ! plutôt que de la mettre déjà en place.

 

Mais vu ta réponse je pensais encore mal :(



#4 FKDEV

FKDEV

    Broyeur de fèves

  • Artisan chocolatier
  • PipPipPipPipPipPip
  • 1 660 messages

Posté 06 février 2017 - 13:33

Ton approche est logique, et valable dans d'autres contextes, mais ce n'est pas de cette manière que fonctionnent les table view sous iOS.
 
Pour des questions d'efficacité mémoire et de vitesse d'exécution, ce n'est pas toi qui mets des cellules dans la tableview, c'est elle qui te demande ce qu'elle contient quand elle a besoin de le savoir.
 
Pour répondre à ses besoins, tu implémentes le protocol UITableViewDataSource.
Généralement, on implémente ce protocol dans le view controller qui gère la vue dans laquelle tu as mis ta table view.
Si ta vue ne contient que la table view, tu peux utiliser la classe UITableViewController comme controller.
 
Au minimum ton objet qui implémente le protocol datasource doit répondre à ces deux questions :
 

func tableView(UITableView, numberOfRowsInSection: Int)

func tableView(UITableView, cellForRowAt: IndexPath)

 
La première méthode est appelée dès que la table view doit s'afficher. tu dois renvoyer le nombre total de cellules dans ta vue (tu verras les sections plus tard).
 
La deuxième méthode te demande de renvoyer la cellule à afficher pour une certaine ligne.

Exemple de ce qu'il faut faire au minimum :

//via https://github.com/codepath/ios_guides/wiki/Table-View-Guide

import UIKit

class ViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!

    let data = ["New York, NY", "Los Angeles, CA", "Chicago, IL", "Houston, TX",
        "Philadelphia, PA", "Phoenix, AZ", "San Diego, CA", "San Antonio, TX",
        "Dallas, TX", "Detroit, MI", "San Jose, CA", "Indianapolis, IN",
        "Jacksonville, FL", "San Francisco, CA", "Columbus, OH", "Austin, TX",
        "Memphis, TN", "Baltimore, MD", "Charlotte, ND", "Fort Worth, TX"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
    }

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }


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

Ici on suppose que la tableview est déjà créée mais tu peux la créer dans la méthode viewDidLoad.
Depuis qu'on utilise Autolayout, il plus pratique de créer et de positionner les vues dans un storyboard.
Mais tu peux toujours le faire dans le code en créant toutes les contraintes Autolayout à la main. quand je le fais, j'utilise les macros d'Erica Sadun (mais il y a surement plus récent).

 
Petite précision sur dequeueReusableCell :
En plus du principe du datasource, il ya le fait que les cellules peuvent être recyclées. Ce n'est pas obligatoire. Par exemple si tu n'as qu'une poignée de cellules à afficher tu peux te passer du recyclage, comme dans l'exemple ci-dessus.
 
dequeueReusableCell est utilisé pour obtenir une nouvelle cellule (elle sera créée ou issue d'un recyclage).
L'identifiant correspond au type de cellule que tu veux créer (tu peux faire cohabiter des cellules qui ont des formats différents).
Tu dois utiliser register(_:forCellReuseIdentifier) pour faire correspondre ton identifiant à ton type de cellule avant l'affichage, par exemple dans ViewdidLoad.

 

 

Il y a des centaines de tuto sur le sujet. Il faut juste en trouver un le plus récent possible.


  • toolsDev aime ceci

#5 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 599 messages
  • LocationParis

Posté 06 février 2017 - 13:41

Quelques tutos français en vidéo sur le sujet : http://pagesperso.li.../semaine-08.php


  • toolsDev aime ceci

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#6 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 06 février 2017 - 15:30

Je vais tout reprendre que ça soit bien clair.
 
Mon principal soucis est que je construit des boutons en fonction du nombre de table que j'ai en base. Si dans ma base j'ai 5 tables, j'aurais 5 boutons portant leur nom.
 
là, où je bloque, c'est que mes index(sender) pour savoir sur quel bouton l'utilisateur a appuyé est passé en paramètre dans une méthode pour exécuter une requête (celle qui doit affiché dans ma fameuse tableView, qui à ce moment là n'est pas visible)
 
exemple, je clique sur le bouton consoles et voici la requête que je souhaite afficher dans la tableView :
("nom", "GameCube")
("id", 8)
("nom", "Wii")
("id", 9)
("nom", "PS3")
("id", 10)
("nom", "PS4")
("id", 11)
("nom", "3DS")
("id", 12)
("nom", "XBOX360")
("id", 13)
("nom", "DS")


En fait, un tableau à plusieurs entrées serait parfait ! (comme ce qu'on à en java JTable...)



#7 Larme

Larme

    Broyeur de fèves

  • Artisan chocolatier
  • PipPipPipPipPipPip
  • 1 949 messages
  • LocationParis

Posté 06 février 2017 - 16:15

My 2 cents :
Essaye d'abord de faire avec une UITableView dans un Storyboard/xib.

Ensuite, passe ensuite ta UITableView (au niveau du rendering) uniquement par code.

 

Pourquoi ?

J'ai l'impression que tu as d'abord un soucis avec ton modèle (construction et implémentation du dataSource), et du coup, tu te rajoutes une complication en plus en voulant faire l'UI aussi uniquement par code.


Tant que vous avez des dents, mangez des pommes. Tant que vous avez de l'argent, croquez la Pomme.

#8 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 février 2017 - 18:49

Si tu veux changer ce que la tableView montre, il suffit de changer la liste que tu utilises pour fournir les données. Ce n'est pas nécessaire de changer la tableView. C'est les méthodes du delegate qui fournissent les données.

 

Et il faut cinq méthodes pour les boutons, c'est bien plus simple que devoir récupérer les "senders".

 

Du coup, tu aurais qqch comme :

{
  var liste1: [...]
  
  var liste2: [...]

  var liste3: [...]

  var liste4: [...]

  var liste5: [...]
  
  var listeActuelle: [...]

  @IBAction func bouton1()
  {
    listeActuelle = liste1
    
    tableView.reloadData()
  }
  
  @IBAction func bouton2()
  {
    listeActuelle = liste2
    
    tableView.reloadData()
  }
  
  @IBAction func bouton3()
  {
    listeActuelle = liste3
    
    tableView.reloadData()
  }
  
  @IBAction func bouton4()
  {
    listeActuelle = liste4
    
    tableView.reloadData()
  }
  
  @IBAction func bouton5()
  {
    listeActuelle = liste5
    
    tableView.reloadData()
  }
  
  ...
}
  public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  {
    return listeActuelle.count
  }
  
  public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  {
    let cell = tableView.dequeue...
    
    let selectedObject = listeActuelle[indexPath.row]
    
    cell.object = selectedObject
    
    return cell
  }



#9 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 février 2017 - 19:20

'... En fait, un tableau à plusieurs entrées serait parfait ! (comme ce qu'on à en java JTable...)


UITableView ne marche pas du tout comme JTable.

JTable est rempli avant de l'utiliser.

UITableView est rempli dynamiquement des méthodes du dataSource et on peut changer les données à n'importe quel moment.
  • toolsDev aime ceci

#10 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 06 février 2017 - 20:56

Pour aller doucement et bien comprendre, j'ai un gros soucis de compréhension sur les types :

Cannot subscript a value of type '[Any]' with an index of type 'IndexPath'

j'ai mes données (provenant de ma requête/méthode) sous forme d'un tableau var arrayDataTable:[Any] = [] :

("nom", "GameCube")
("id", 8)
("nom", "Wii")
("id", 9)
("nom", "PS3")
("id", 10)
("nom", "PS4")
("id", 11)
("nom", "3DS")
("id", 12)
("nom", "XBOX360")
("id", 13)
("nom", "DS")

et au niveau de 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        
        guard var connexion = ConnexionSQLite.sharedInstance else
        {
            print("Erreur de connexion")
        }
        
       // donc voilà ce que je voudrais faire, mettre dans cell.textLabel?.text mon tableau de données arrayDataTable:[Any] = []
        cell.textLabel?.text = connexion.arrayDataTable[indexPath.row]
        return cell
    }

Donc, je sais que cell.textLabel? = "attends" un type String, mais je lui affecte un type Any...

et même en le parsant (as! Any) j'ai cette erreur de compilation.

 

voilà, :(



#11 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 février 2017 - 23:50

Il faut créer ta propre cellule en ajoutant les labels ou autres choses, puis tu devrais ajouter une var du type des données qui tu veuilles passer à la cellule. Dans le didSet, tu peux là écrire le code pour assigner les données aux labels.
  • toolsDev aime ceci

#12 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 599 messages
  • LocationParis

Posté 07 février 2017 - 00:33

 

Donc, je sais que cell.textLabel? = "attends" un type String, mais je lui affecte un type Any...

et même en le parsant (as! Any) j'ai cette erreur de compilation

a

Tu sais que Xcode attend un String, alors tu cherches à convertir un [Any] en un Any   ???

Pourquoi ne pas convertir le [Any] en un .. String ?

d

// Tableau de type [Any]
let connexion:[Any] = ["GameCube",
                       "Wii",
                       "PS3",
                       "PS4"]
// Lecture d'une ligne 
let index = 1 
let str = connexion[index] as! String
print (str)

Wii


  • toolsDev aime ceci

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#13 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 599 messages
  • LocationParis

Posté 07 février 2017 - 01:38

J'ai l'impression que tu maitrises mal les conversions de type en Swift. 

let data = ["New York, NY", "Los Angeles, CA", "Chicago, IL", "Houston, TX",
        "Philadelphia, PA", "Phoenix, AZ", "San Diego, CA", "San Antonio, TX",
        "Dallas, TX", "Detroit, MI", "San Jose, CA", "Indianapolis, IN",
        "Jacksonville, FL", "San Francisco, CA", "Columbus, OH", "Austin, TX",
        "Memphis, TN", "Baltimore, MD", "Charlotte, ND", "Fort Worth, TX"]

a

Dans l'exemple de code donné par FKDEV, le tableau data est de type [String]. C'est le type de base quand on tape quelque chose comme :

a

let tableau = ["Chaine A", "Chaine B", "Chaine C"]

qa

Ce qui lui permet de lire directement le tableau pour obtenir un String

a

...
cell.textLabel?.text = data[indexPath.row]
...

a

Pour être dans les mêmes conditions que toi, j'ai créé un tableau de [Any], en précisant sa nature:

let connexion:[Any] = ["GameCube",
                       "Wii",
                       "PS3",
                       "PS4"]

a

Pour avoir un String je dois lire un Any dans le tableau et le convertir  :

a

let index = 1 
let str = connexion[index] as! String

A lire le message d'erreur :

a

 

 

Cannot subscript a value of type '[Any]' with an index of type 'IndexPath'

a

j'ai l'impression que ton tableau de [Any] n'est PAS un tableau, mais juste un Any contenant plein de trucs dedans.

guard var connexion = ConnexionSQLite.sharedInstance else
        {
            print("Erreur de connexion")
        }
cell.textLabel?.text = connexion.arrayDataTable[indexPath.row]

Je ne sais pas trop ce que tu récupères avec ta connexionSQLite (je ne comprend rien du tout à SQL), mais ce n'est certainement pas un tableau de String bien structuré, utilisable par Swift.

 

EDIT : J'ai relu le début du post. Ton problème est bien plus compliqué que de lire le contenu d'un tableau. Tu as un flux de données contenant différentes informations. Il faut analyser ce flux pour en extraire les informations et les stocker quelque part avant de les utiliser. C'est un problème distinct de l'utilisation d'un UITableView.


  • toolsDev aime ceci

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#14 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 07 février 2017 - 10:30

 

Si tu veux changer ce que la tableView montre, il suffit de changer la liste que tu utilises pour fournir les données. Ce n'est pas nécessaire de changer la tableView. C'est les méthodes du delegate qui fournissent les données.

 

Et il faut cinq méthodes pour les boutons, c'est bien plus simple que devoir récupérer les "senders

J'arrive pourtant très bien à récupérer le bon index et à le passé en paramètre dans ma méthode qui "requête" la base en fonction du choix de l'utilisateur.

Mon réelle soucis est comme expliquer plus bas, est bien le type ("Row") que je récupère directement depuis ma requête via GRDB.swift :( Impossible de itéré ce "faux" tableau...

 

Tu sais que Xcode attend un String, alors tu cherches à convertir un [Any] en un Any   ???

Pourquoi ne pas convertir le [Any] en un .. String ?

alors comme tu as put le lire dans le quote du code, j'ai cité le soucis.

c'est juste une erreur de ma part j'ai bien sur tenté un parse en String  ;) mais sans succès.

 

// Tableau de type [Any]
let connexion:[Any] = ["GameCube",
"Wii",
"PS3",
"PS4"]
// Lecture d'une ligne
let index = 1
let str = connexion[index] as! String
print (str)

 

Et non :) pas si simple que ça malheureusement (enfin pour moi)

J'ai un tableau Brut sans clé/valeur, c'est bien GRDB.swift qui me mène la vie dur et non ma méthode.

Dans le sens, ou je ne peut rien parser ou pire parcourir...

 

 

EDIT : J'ai relu le début du post. Ton problème est bien plus compliqué que de lire le contenu d'un tableau. Tu as un flux de données contenant différentes informations. Il faut analyser ce flux pour en extraire les informations et les stocker quelque part avant de les utiliser. C'est un problème distinct de l'utilisation d'un UITableView.

 

Tout à fait  ;)

J'allais vous le redire hier... Mon soucis est que je n'ai pas la main sur GRBD.swift et il me renvois un tableau dont je ne peut rien parsé (à ma connaissance, sans le traité AVANT...)

 

J'aurais bien aimer que ma requête renvois un dictionary: clé/valeur.

du coup je me retrouve avec un tableau brute ou comme tu le signales un flux, inutilisable, finalement BEAUCOUP d'énergie pour pas grand chose encore...

Pourquoi cela n'est il pas aussi simple ?... une requête dans un tableau, je parcours ce tableau et basta... 

Si je dois ENCORE changer de framework... ou si vous avez des idées sur une façon simple de récupérer directement ma requête en dictionary ou array je suis preneur ?

 

Edit :

je réitère ma demande (de mon autre poste)

VOUS qu'est ce que vous utilisez pour avoir la main sur vos requêtes SQLite et en même temps de "simple" ?

Je ne comprends vraiment pas ce système usine à gaz :(



#15 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 599 messages
  • LocationParis

Posté 07 février 2017 - 11:12

Je ne connait rien à SQL, encore moins à SRBD.swift, mais en faisant une recherche simple sur Google, on trouve de la documentation et des exemples d'utilisation :

 

http://cocoadocs.org...DB.swift/0.4.0/

 

Tu devrais trouver ton bonheur dedans, non ?


  • toolsDev aime ceci

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#16 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 07 février 2017 - 11:20

merci pour ton geste, vraiment ;)

 

mais, avant de posté je cherche toujours (de mon mieux) et pour ça aucun soucis.

J'ai trouvé comment "requêter" Mais, le soucis est bien ce que me ramène GRDB.swift... C'est à un tableau(brut) que je ne sais pas parcourir visiblement...

je te met mon code que tu vois (il n'y à rien de compliquer) :

            // -------------------------------------------------------
            // ---- récupère toutes les données de chaque table : ----
            // -------------------------------------------------------
            let dataTables = try connexion?.inDatabase{db in try Row.fetchAll(db,"SELECT * FROM \(table)")}
            for dataTable in dataTables!
            {
                // Je parcours et ajoute dans un tableau globale toutes les infos pour chaque colonne/ligne
                // Le réellement soucis est ici :) à chaque itération, il me met dans les "clé/valeur" ensemble...
                for data in dataTable
                {
                    self.arrayDataTable.append(data)
                }
            } 

pas de clé/valeurs ! et ça, c'est pénible...

je n'ai aucun soucis coté SQL, je me débrouille bien de ce coté :) (en même temps je fais du très simple... la seule requêtes "compliquer" est celle pour récupérer dynamiquement toutes les tables de ma base...)

 

Non, mon vrai soucis est de traiter l'info !

C'est vraiment pénible pur pas grand chose (enfin de mon point vue) 

Je me doute que vous, vous aillez l'habitude, mais franchement SQL et ios :( ... c'est pas simple pour rien du tout...

 

Edit:

je rajouterais que je souhaite tout récupérer au lancement de l'application, pour tout mettre dans un tableau et du coup, ne plus faire de requêtes.

Cela rest bien mieux niveau performances, de mon point vue. Une requête, un fois, une affectation dans un tableau/dico... puis des itérations clé/valeur.



#17 Larme

Larme

    Broyeur de fèves

  • Artisan chocolatier
  • PipPipPipPipPipPip
  • 1 949 messages
  • LocationParis

Posté 07 février 2017 - 11:38

Il faudrait revenir sur ton topic précédent parlant de GRDB.swift.
 
Si j'en crois leur Read.me 
 
try dbQueue.inDatabase { db in
    let rows = try Row.fetchCursor(db, "SELECT * FROM pointOfInterests")
    while let row = try rows.next() {
        let title: String = row.value(named: "title")
        let isFavorite: Bool = row.value(named: "favorite")
        let coordinate = CLLocationCoordinate2DMake(
            row.value(named: "latitude"),
            row.value(named: "longitude"))
    }
J'ai l'impression que toi tu fais un truc bizarre an ayant:
("nom", "GameCube")
("id", 8)
("nom", "Wii")
("id", 9)
("nom", "PS3")
("id", 10)
("nom", "PS4")
("id", 11)
("nom", "3DS")
("id", 12)
("nom", "XBOX360")
("id", 13)
("nom", "DS")
 

Comme l'avait signalé la nounourse Joanna, il faut que tu aies une classe qui représente ton object correctement, représentant ce que faut ton object fetché.
 
 

En Objective-C, j'aurais :
@interface Console : NSObject
@property (nonatomic, strong) NSString *consoleName;
@proprety (nonatomic, assing) NSInteger consoleID;
@end

@implementation Console
-(id)initWithName:(NSString *)name andID:(NSInteger)uniqueID
{
    self = [super init];
    if (self)
    {
        _consoleName = name;
        _consoleID = uniqueID;
    }
}
@end
 
Lors du fetch, je ferais alors quelque chose du genre (pseudo code) :
while (rows.next)
{
   Console *uneConsole = [Console alloc] initWithName:[row valueForName:@"title"] andID:[row valueForName:@"id"];
   [monBigArray addObject:uneConsole];
}
Or, j'ai l'impression que toi tu fais quelque chose du genre:
while (rows.next)
{
   [monBigArray addObject:[row valueForName:@"title"]];
   [monBigArray addObject:[row valueForName:@"id"]];
}
Pour faire du pseudo code Swift:
try dbQueue.inDatabase { db in
    let rows = try Row.fetchCursor(db, "ta requête")
    while let row = try rows.next() {
        let console: Console = Console()
        console.name = row.value(named: "name")
        console.uniqueID = row.value(named: "id")
        monBigArray.addObject(console)
    }

  • toolsDev aime ceci
Tant que vous avez des dents, mangez des pommes. Tant que vous avez de l'argent, croquez la Pomme.

#18 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 février 2017 - 11:47

En Objective-C, j'aurais :

@interface Console : NSObject
@property (nonatomic, strong) NSString *consoleName;
@proprety (nonatomic, assing) NSInteger consoleID;
@end

@implementation Console
-(id)initWithName:(NSString *)name andID:(NSInteger)uniqueID
{
    self = [super init];
    if (self)
    {
        _consoleName = name;
        _consoleID = uniqueID;
    }
}
@end
 
Lors du fetch, je ferais alors quelque chose du genre (pseudo code) :
while (rows.next)
{
   Console *uneConsole = [Console alloc] initWithName:[row valueForName:@"title"] andID:[row valueForName:@"id"];
   [monBigArray addObject:uneConsole];
}

 

Et, en Swift, tu aurais :

struct Console
{
  let id: Int
  
  let nom: String
}
while let row = try rows.next()
{
   let console = Console(id: row.value(named: "id"), nom: row.value(named:"nom"))

   self.consoles.append(console)
}

  • toolsDev aime ceci

#19 toolsDev

toolsDev

    Cueilleur de cabosses

  • Membre
  • PipPipPip
  • 93 messages

Posté 07 février 2017 - 11:51

Il faudrait revenir sur ton topic précédent parlant de GRDB.swift.
 
Si j'en crois leur Read.me 
 

try dbQueue.inDatabase { db in
    let rows = try Row.fetchCursor(db, "SELECT * FROM pointOfInterests")
    while let row = try rows.next() {
        let title: String = row.value(named: "title")
        let isFavorite: Bool = row.value(named: "favorite")
        let coordinate = CLLocationCoordinate2DMake(
            row.value(named: "latitude"),
            row.value(named: "longitude"))
    }

 

J'ai l'impression que toi tu fais un truc bizarre an ayant:

 

("nom", "GameCube")
("id", 8)
("nom", "Wii")
("id", 9)
("nom", "PS3")
("id", 10)
("nom", "PS4")
("id", 11)
("nom", "3DS")
("id", 12)
("nom", "XBOX360")
("id", 13)
("nom", "DS") 

ce que tu m'indiques est fait :

            // récupère toutes les tables :
            let tables = try connexion.inDatabase{db in try Row.fetchAll(db,"SELECT name FROM sqlite_master WHERE type = 'table' AND name <> 'sqlite_sequence'")}
            for table in tables
            {
                // ---------------------------------------------
                // ---- récupère les noms de chaque table : ----
                // ---------------------------------------------
                let nomTable:String = table.value(named:"name")
                self.arrayNomTable.append(nomTable)
            }

mais pour les champs je les veut tous... du coup je suis bloquer avec un tableau qui agglomère clé/valeur, et je ne peut pas les distingués.

Mais quand je tente la même chose pour les données (lignes)


            // -------------------------------------------------------
            // ---- récupère toutes les données de chaque table : ----
            // -------------------------------------------------------
            let dataTables = try connexion?.inDatabase{db in try Row.fetchAll(db,"SELECT * FROM \(table)")}
            for dataTable in dataTables!
            {
                for data in dataTable
                {
                   let id:Int = data.value(named:"id")
                   let name:String = data.value(named:"name")
//erreur de compilation...
Value of tuple type '(String, DatabaseValue)' has no member 'value'
                }
            }

Bon, je vais réfléchir à tout ça, j'avoue je suis paumé là ! soucis de conception, peut être, mais GRDB.swift est pas très lisible pour moi.

Mappé ? oui bien sur mais je ne souhaite pas une classe "Jeux" (par exemple) statique... je veux du dynamique, tu vois ?

si ma table à des ajout de colonne, car si je fait un ORM je dois lui renseigner a la mano toutes les colonnes...

Voilà ma vision.



#20 Larme

Larme

    Broyeur de fèves

  • Artisan chocolatier
  • PipPipPipPipPipPip
  • 1 949 messages
  • LocationParis

Posté 07 février 2017 - 11:57

Tant que tu n'aurais pas réussi à le faire/comprendre en "statique" comme tu dis, tu auras du mal à le faire en "dynamique".

Et tu auras tout de même un soucis à l'affichage, dans tous les cas.

Tu te rajoutes une dose de complexité, qui te ralentis énormément. Tu as besoin d'abord de maîtriser des concepts.


  • Joanna Carter aime ceci
Tant que vous avez des dents, mangez des pommes. Tant que vous avez de l'argent, croquez la Pomme.




0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)