Les bindings: simple ou complexe ?
Pyroh
Membre
Faut arrêter les bindings c'est simple. Il faut pas en avoir peur c'est tout.
Il y a pleÌthore de tutos sur le net pour ça.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Faut arrêter, les bindings, c'est compliqué. Il faut se limiter à une utilisation basique.
Aucun tuto n'approfondit le sujet.
Donne moi un seul exemple concret qui te permet d'avancer une telle chose.
Pour les tutos c'est vrai qu'il faut assez souvent savoir approfondir soit-même.
Oui, voici le premier exemple concret qui me vient à l'esprit.
On a une liste de formes géométriques, des cercles et des carrés. On doit pouvoir par binding:
- modifier leur centre
- modifier leur couleur de remplissage
- modifier le côté des carrés sélectionnés
- modifier le rayon des cercles sélectionnés
L'essence du problème est que la liste de formes n'est pas homogène. Si on binde sur la propriété "rayon" du NSArrayController et qu'on y met des carrés, on obtient un superbe plantage du Key-Value Coding pour cause de clef inconnue.
La solution est de parcourir la sélection, voir si toutes les formes ont une propriété "rayon" et seulement là afficher les textfields qui sont bindés sur "rayon".
C'est loin d'être simple!
Bah si, ce cas de figure est simple et sans ligne de code si ce n'est la définition du modèle.
Bon allé l'exercice était sympa à faire. Et rapide aussi. J'ai un peu fignolé l'interface mais en 30 minutes ça tournait correctement.
Voilà le seul code lié à la partie contrôleur :
On peut avoir le code ici :
J'avoue que tu as trouvé une solution bien plus simple que la mienne, à savoir binder la visibilité des StackViews sur selection.radius avec le ValueTransformer NSIsNil.
Comment sait-on qu'on peut faire ça ??? Où se trouve la doc qui dit que le proxy selection renvoie nil si la clef n'existe pas ? En dix ans de bindings, je ne le savais pas, et pourtant j'ai lu et relu les docs.
C'est justement ça qui m'ennuie tant avec les bindings. Il y a un tas de comportements implicites.
Et d'autres choses qui paraissent faisables ne le sont pas.
Un autre exemple difficile à implémenter:
Le modèles contient des formes, disons des cercles. Il ont un centre et une couleur de remplissage. Ils ont tous le même rayon.
L'exercice consiste à créer une sous-classe de NSView qui permet de sélectionner les cercles et de les déplacer.
Pour le coup, c'est faisable en lisant la doc, mais c'est très complexe au niveau de la vue, parce qu'il faut gérer les différents états de la sélection dans le NSArrayController.
Une dernière chose que je me refuse à faire avec les bindings, ce sont les NSOutlineViews. C'est compliqué, et ça impose que le modèle ait une certaine forme. ça peut devenir carrément un cauchemar si on doit gérer le glisser-déposer.
Si je trouve la solution de Pyroh à ton problème particulièrement élégante, pour le coup, concernant les NSOutlineView, je suis entièrement d'accord avec toi : le binding est un cauchemar.
Et c'est encore pire si on doit raccrocher le tout à des structures Core Data (et ses NSOrderedSet non directement pris en charge par le binding des NSOutlineView) !
Alors comment on sait ça ? Si tu prends en compte que les bindings c'est l'association de deux design patterns principaux : observer et proxy. Tout ça fait que la propriété selection du controller et les fameux arrangedObjects ne sont pas stricto sensu des vrais objets mais des proxies qui ne vont pas reÌpondre spécifiquement de la meÌ‚me manière qu'une sous-classe NSObject standard.
Dans le cas qui nous intéresse c'est l'impleÌmentation de value(forUndefinedKey:) qui est diffeÌrente dans le proxy et qui va au choix remonter une exception ou renvoyer un objet de type NSNotApplicableMarker. Si on a mis raisesForNotApplicableKeys aÌ€ false on aura cet objet speÌcial dans la valeur passeÌe à la meÌthode setValue(_:forKeyPath:) du contrôle qui est bound.
Dans le binding de l'exemple que je donne il y a deux composants vraiment essentiels dans la configuration du binding :
- Raises For Not Applicable Keys qui doit être décoché sous peine d'exception à l'exeÌcution.
- Not Applicable Placeholder nous donne la valeur par deÌfaut du binding si justement la cleÌ n'existe pas.
Ce qui montre bien que le cas est preÌvu. En plus il est documenteÌ dans ce magnifique ( :P) document qu'est Bindings Message Flow.
Sinon pour ce qui est de la vue custom le plus difficile va être la gestion interne de la vue avec les events et tout le bordel. Pas le binding en lui meÌ‚me. Malheureusement je ne pense pas avoir le temps de le faire aujourd'hui il me faudrait au moins une bonne heure pour avoir un truc qui marche et encore autant pour le coup de polish.
La NSOutlineView j'en ai deÌjaÌ€ fait une mais je pense que c'eÌtait avec une datasource je dois voir si je retrouve le code si je l'ai archiveÌ pour être suÌ‚r.
J'ajouterai aussi à l'exemple un colorwell qui reÌagis un peu mieux aux fameux markers de binding, j'en ai deÌjaÌ€ écrit un. ça peut être inteÌressant pour les novices.
AlleÌ hop un petit repo GitHub qui va bien : https://github.com/Pyroh/ComplexBindings
Pour préciser, je ne suis pas anti-bindings, mais mon expérience est qu'ils n'apportent généralement pas de gain de temps, parce qu'on en perd beaucoup au débogage.
Non je le vois plus comme deux questions logique :
- Est-ce que je me plains si je ne trouve pas ce que je cherche?
- Qu'est-ce que j'affiche à la place de me plaindre ?
L'info est dure à trouver et il faut de l'expeÌrience dans ce domaine preÌcis pour le savoir mais je trouve ça moins contraignant que le boilerplate qui viendrait en lieu place.
Le lien view <> controller est une saloperie à mettre en place quelque soit la meÌthode utiliseÌe. Les bindings ont l'avantage d'être plus simple et plus rapide à mettre en oeuvre une fois qu'on a compris le truc. Mais il faut le comprendre, pouvoir prendre le temps, se casser les dents un nombre incalculable de fois et lire beaucoup de doc. Pareil pour le debugging une fois que tu sais ce que tu fais tu y recours beaucoup moins souvent.
C'est aussi non-exportable comme knowledge et je sais que ça c'est quelque chose que tu n'aime pas.
Et c'est une composante essentielle du développement macOS. Un développeur macOS seÌrieux doit maitriser les bindings selon moi...
Et CoreData mais c'est une autre histoire :P
J'ai impleÌmenteÌ un color well custom qui montre comment on peut reÌpondre aux diffeÌrents markers. J'ai tout pousseÌ sur le repo.
Ça intéresse quelqu'un que je creuse un peu plus le sujet ? Avec du code et du bla bla qui l'explique bien suÌ‚r.
Si je suis motiveÌ je ferai une petite vue graphique avec les formes. C'est en gros comme une table view dans l'idée et je vois déjà comment faire.
J'avoue ne rien y comprendre. Bon, je n'ai jamais essayé, cela n'existant pas sous iOS. Une raison pour laquelle Apple n'a pas implémenté les bindings sur son OS mobile ?
Nous pourrions parler de Metal, Core Image, Core Data, mais puisque le sujet est les bindings, je vais dire comment je vois ça.
Je suis d'accord avec toi quand tu dis que la connexion Vue-Contrôleur est une galère partout et que toute solution technique pour y aider est intéressante. C'est juste que les bindings ne me semblent pas un outil particulièrement probant. Pas seulement parce que c'est basé sur des notions compliquées (franchement, si tu comprends vraiment la gestion des collections en KVC, écris un livre sur le sujet), mal implémentées (KVO), mal documentées, et plus trop supportées par Apple.
Mais aussi parce que mon expérience m'a démontré qu'il y avait des cas où cette solution ne fonctionne pas (par ex. des limites inhérentes au principe des NSValueTransformers), et surtout que ça devient galère quand le programme grossit.
Les KVC, KVO et Bindings sont basés sur des chaà®nes de caractères et résolus à l'exécution. Et les conséquences au quotidien me gavent. J'ai beau avoir une bonne couverture en tests unitaires, je ne suis pas fichu de te dire si l'appli fonctionne sans la lancer et tester tous les cas possibles.
En effet, il est très possible qu'on binde sur une clef du Modèle qui n'existe plus. C'est ce qui se produit quand on a une appli conséquente, parce que le Modèle change souvent: les clefs sont renommées, disparaissent, passent d'une collection à une simple valeur, etc. Les facultés limitées pour le refactoring de Xcode n'aident pas.
Alors certes, tu vas me dire que de toute façon, il faut quand même faire des tests manuels, et que les bugs se resolvent facilement. Mais au final, ce sont des demi-heures perdues qui se cumulent en jours improductifs, et de nouveaux bugs qui réapparaissent sans-cesse.
Alors que Cocoa était basée sur le dynamisme d'Objective-C, le passage à Swift destine au statique. Et je vais te dire que même si ça pose de nouveaux problèmes techniques, moi ça me convient, parce que j'en ai marre de jouer au petit singe qui clique sur des boutons.
Au final, je choisis juste les outils qui me paraissent les meilleurs " ou les moins mauvais. J'assume qu'il y a une part subjective dans ces choix.
Tu vas être surpris, mais je suis d'accord avec toi. Mais c'est parce qu'il n'existe pas d'alternative sérieuse. Peut-être que quelque chose comme RxSwift va s'améliorer. Note que c'est une solution qui m'intéresse parce que quand ça compile, ça marche. Que les concepts de la programmation réactive soient multi-plateformes est un plus, mais avoir le code source davantage.
Là pour le coup, je ne suis pas d'accord. Core Data n'a jamais été une bonne ORM. Le principe même des ORM est douteux. Et on dispose d'alternative largement plus crédibles.
Pour mon dernier développement, j'ai utilisé GRDB, une surcouche à SQLite écrite en Swift. Comparé à Core Data, c'est du bonheur.
Je partage ton avis, les bindings sont perfectibles en beaucoup de points. Moi j'ai toujours trouveÌ ça fantastique alors j'ai passeÌ un certain temps à les eÌtudier, lire sur le sujet, tester et hacker un peu le concept. Parce que j'ai le temps. Le dev iOS/macOS n'est pas mon meÌtier donc je ne cours pas après le temps et la rentabiliteÌ est une notion qui n'a pas cours quand on parle de passe temps.
Je comprends que quand tu compte dessus pour bouffer tu ne peux pas passer 4/5 jours à fouiller juste pour savoir comment ça marche. Dans mon vrai travail je bosse aussi comme ça, y'a une doc et je la suis je ne vais pas commencer à aller chercher dans les arcanes. Et je ne travaille pas tout seul aussi j'ai des gens avec qui je peux partager l'expeÌrience.
Mais pour le deÌbutant qui code mac en dilettante il a le luxe d'approfondir et se doit d'explorer les bindings si il est un minimum seÌrieux.
Sinon au passage merci pour GRDB je vais y regarder de beaucoup plus preÌ€s maintenant que je suis en congeÌ, un peu...