[RESOLU] Problème liste "Select" en swift ?
Bonjour,
Ayant fait un peu le tour du forum, j'ai l'impression qu'il y a des gens assez compétents ici pour pouvoir m'aider (et en français aussi, ça fait plaisir ^^)..
J'ai un petit soucis de conversion de type et je ne sais pas comment le résoudre..
En gros, j'utilise Eureka pour créer un formulaire, dedans j'ai une liste dont je récupère les valeurs en json (j'utilise SwiftyJson pour manipuler tout ça..)
Le soucis, c'est que je n'arrive pas à mettre les valeurs de la liste que je reçois en json, dans le "PushRow" de mon formulaire.. en gros, j'ai pas les valeurs de ma liste quand je clic dessus..
Je vais vous détaillez le code, ça sera peut-être plus parlant..
Le json que je reçois :
{
"listValue": [{
"id": 1,
"value": "Value 1"
},{
"id": 2,
"value": "Value 2"
},{
"id": 3,
"value": "Value 3"
}]
}
1/ J'ai déclaré une structure pour bloquer les valeurs id et value :
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
}
2/ Je l'ai rendu "Equatable"
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
}
extension MyStruct: Equatable {}
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
let areEqual = lhs.id == rhs.id &&
lhs.value == rhs.value
return areEqual
}
3/ Puis CustomStringConvertible
struct MyStruct : CustomStringConvertible {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
var description: String {
return "\(self.id)"+" "+"\(self.value)"
}
}
extension MyStruct: Equatable {}
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
let areEqual = lhs.id == rhs.id &&
lhs.value == rhs.value
return areEqual
}
J'ai fais tout ça car c'est ce qu'on m'a conseillé sur un autre forum..
J'ai donc essayé de mettre les valeurs que je récupère en json dans mon "PushRow" et là , ça ne passe pas..
<<< PushRow<MyStruct>(idItem) {
$0.title = item["libItem"].stringValue
$0.options = item["listValue"].dictionaryValue // Erreur ici
Je me retrouve avec un message d'erreur me disant : Cannot assign value of type '[String : JSON]' to type '[MyStruct]'
Ma "listeValue" est un objet SwiftyJSON..
Comment la convertir pour la rendre compatible avec ma structure (MyStruct) ?
Est-ce-que je me dirige dans le bon sens pour afficher une liste "dynamique" ?
Si ça se trouve, il y a une façon de faire beaucoup plus simple ?
Merci de votre aide
Réponses
Bon, j'ai revu mon code et fait quelque chose de plus simple.. ça aidera peut-être à mieux comprendre le soucis..
En gros, j'utilise un PushRow (d'Eureka)
Mon json listValue est toujours le même..
Du coup, c'est bon, j'ai bien mes valeurs dans la liste, je peux choisir celle qui me convient, etc etc..
Le soucis vient à la validation du formulaire, je me retrouve avec le texte (value) sélectionné et pas la valeur (id)..
Ce qui est normal car je ne sais pas comment l'intégré dedans.. mais je voyais plus une utilisation comme la balise "select" en html..
Et que la validation du formulaire me retourne 1 ou 2 .. et pas le libellé..
Bref, du coup, est-ce-que quelqu'un à une idée de comment faire ça ?
Ou j'utilise peut-être pas les bons trucs pour faire des formulaires simplement ?
Qu'utilisez-vous pour faire des formulaires assez complets ?
Merci de votre aide
Personnellement, ce n'est pas que je n'ai rien à cirer de ton problème, mais je n'ai jamais utilisé Eureka, alors j'ignore comment il s'attend à ce qu'on convertisse les objets JSON en struct.
Oui c'est le soucis avec ce projet, c'est que j'utilise plusieurs trucs ensemble (SwiftyJson, Eureka, etc etc), du coup ça rend le problème bien spécifique et je ne trouve pas beaucoup de personne dans mon cas..
C'est aussi pour ça que j'ai simplifié mon code, essayé de rendre le truc un peu plus générique dans mon deuxième post.
Du coup, as-tu un exemple de listebox faite en swift ?
Qu'utilise tu pour faire tes formulaires avec des règles de vérification ?
Je me dis qu'il y a peut-être un truc plus simple dont je ne connais pas l'existence..
Quand tu fais ça :
Tu dis que la donnée associé à ta ligne sera de type MyStruct. Le problème c'est qu'ensuite tu passes une donnée de type Dictionary ici, alors que tu devrais passer un tableau de MyStruct
Après je ne connais pas eureka, donc je ne sais pas comment il va transformer MyStruct en un texte à afficher. Logiquement MyStruct devrait satisfaire à un protocole qui lui permettent de récupérer le texte à afficher pour une valeur donnée.
Swift possède déjà un tel protocole qui s'appelle CustomStringConvertible
Donc, je suppose que si tu implémente CustomStringConvertible dans MyStruct et que tu retournes un texte correpsondant à ton item, cela va surement fonctionner.
Je voudrais bien lui passer un tableau de "MyStruct" sauf que je ne sais pas comment faire, pour moi c'est encore un peu flou de ce côté là
Pour le CustomStringConvertible, c'était déjà le cas dans mon premier post nan ? (le point 3)
Je dirais que le tableau [MyStruct] doit être assigné à $0.options. La valeur de $0.value contient la valeur par défaut représenté par une valeur "MyStruct"
Pour repartir de ton premier exemple:
Je ne connais pas Eureka, mais en regardant en diagonale la documentation c'est ce que je ferais. Ensuite je supposes que tu récupères la valeur sélectionné par l'utilisateur (qui est représenté par un object de type MyStruct).
Le fait de rendre la structure CustomStringConvertible permet d'afficher à l'utilisateur une chaine représentative de ce que contient MyStruct. Je supposes que dans ton cas tu pourrais simplement retourner "value".
Tout cela "À une vache près, hein" â„¢Karadoc.
Ha oui n'oublie pas de laisser un petit post dans la section présentation des membres (sauf si c'est déjà fait).
yep. J'avais pas vu.
Je n'ai pas compris immédiatement leur système de boucle,
mais j'ai trouvé une autre manière de le faire en cherchant un peu (en anglais) :
C'est un cas où le map pourrait avantageusement remplacer le for, mais le for est plus pédagogique.
En tous cas ce sont deux frameworks qui, s'ils font gagner un peu de temps (ça reste à prouver), ne font pas gagner en compréhension de Swift et de la programmation.
Bon et bien à une vache près, ça fonctionne ^^
J'arrive donc au même résultat (en utilisant une structure) que mon deuxième post (avec un tableau de string).
Je trouve la méthode avec une structure mieux, à mon avis, j'vais pouvoir faire plus de chose avec ça..
Je remet le code ici, si ça peut en aider certains :
En fait, maintenant que j'ai le code sous les yeux, je comprends mieux comment on définit un tableau de structure personnalisée et comment le remplir, je bloquais dessus, du coup merci, j'suis sur que ça me resservira
Ensuite, j'ai encore le deuxième soucis qui persiste..
J'ai donc ma liste où je peux choisir mes données (recup' via le json) mais quand je valide le formulaire, je me retrouve avec le texte sélectionné et pas l'id de la valeur.. ce qui est assez embêtant..
Il y a surement un truc que je ne connais pas sur les listes, les structs ou quoique ce soit d'autre pour que ça m'affiche le texte à l'affichage mais que ça renvoi l'id à la validation du formulaire.. .. .. nan ?
Je vois mal ce genre de truc (le fait que ça renvoi le texte affiché) comme comportement par défaut dans une appli..
J'ai pas encore assez de recule pour ça mais je te crois sur parole ^^
En tout cas, merci à vous 2 pour votre aide
Comment récupères tu la valeur de la ligne ?
Depuis ton code idItem étant un tag je ferais un truc du genre
Ah oui, j'suis con, j'ai même pas mis le code
Du coup, c'est Eureka qui récupère toute les valeurs de mon formulaire..
La fonction form.values() ressemble à ça :
A vu de nez, il n'y a pas l'air d'avoir d'option pour choisir ce qu'on veut récupérer
J'ai l'impression que je suis bon pour modifier leur framework et j'aime pas vraiment ça
Dans la boucle for (idvaleur, valeur)... valeur est du type Any?. As tu vérifié que dans le ton cas que valeur n'est pas du type MyStruct justement ? (tu peux peut être l'avoir avec un print("\(laValeur.self)")) (ou dynamicType à la place de self).
Alors avec self.dynamicType, valeur est du type MyStruct ..
Du coup, j'ai modifié ma fonction de récupération des valeurs comme ça :
Du coup, je récupère bien l'id de la valeur et c'est nickel
Je vois maintenant comment mieux utiliser les structures et récupérer leur valeur, ça me sera bien utile ^^
Grand merci à vous 2
L'explication c'est que quand tu fait :
Cela utilise le protocole CustomStringConvertible...
Ouai, j'me suis rendu compte de ça ^^
D'où l'utilisation du tag pour récupérer le champ, puis la valeur qui m'intéresse