Multiview app partager ses variables d'une à  l'autre

Bonjour,


 


Tout d'abord c'est mon premier message sur le forum, donc j'espère l'établir de manière correct, j'entends par là  dans la bonne section et tout ... Si ce n'est pas le cas je vous pries de bien vouloir m'excuser. 


 


Alors voici mon interrogation, j'aurais besoin de votre avis, un peu comme une sorte de "best partice" étant ma première application iOs, je n'ai pas encore l'habitude de certain concept néanmoins j'ai déjà  programmé en de nombreux langages.


 


J'ai crée une application avec plusieurs vues. Elles ont toutes leur propre, fichier .h et .m . 


Mon souhait serait de partager un variable de la vue 3 à  la vue 6.(D'autre vues partagerons leur variable avec la vue 6) Les deux vues ne sont donc pas directement reliée par un segue. Enfaite cette vue 6 a pour but d'afficher les valeurs que l'utilisateur a entré(dans un textfield, ici son pseudo) avant qu'elles ne soient envoyé au serveur (Parse).


 


Après avoir épluché le web 3 possibilités semblent se présenter à  moi :


 


1) utiliser datacore pour contenir ma variable


 


2) utiliser les variables globales 


 


3) utiliser quand même un segue mais cela fera des relations superflues


 


Je me tourne donc vers vous pour d'aiguillé sur la meilleure façon de faire les choses.


Mais aussi la façon de les mettre en place car j'ai vu beaucoup de procéder différent pour chaque méthode.


 


Dans l'attente de vos réponses, je restes à  votre entière disposition pour plus de détails sur ma question.


Je vous remercie par avance de votre attention et vous souhaite une très agréable soirée.


 


Veuillez trouver si joint le storyboard.


 


Vincent Montet


Réponses

  • Bonjour,


     


    - tout d'abord, la coutume veut qu'avant de poster une question, on aille se présenter dans la section adéquate. Outre l'aspect "politesse", c'est surtout pour que l'on sache quelles sont tes connaissances en développement et que l'on adapte nos réponses à  ton niveau. Vraisemblablement, vu ta question, il semble que tu sois débutant en développement iOS... mais peut-être as tu des connaissances dans d'autres domaines du développement (Web, autres langages)


     


    - concernant ta question, les variables globales sont à  proscrire absolument, car elles ne garantissent pas l'aspect "thread-safe" du projet.. Utiliser Coredata ? c'est un peu le marteau pour écraser la mouche... Tu peux plutôt utiliser un delegate, ce sera plus adapté pour une variable...  


  • CéroceCéroce Membre, Modérateur

    Ton application doit être découpée selon le principe MVC.


    Ce que tu veux est partager un objet de la couche Modèle.


    Tu n'as qu'à  le passer d'un View Controller à  l'autre dans la méthode -prepareForSegue...


     


    (C'est concis, mais je t'assure que nous avons expliqué au moins 20 fois comment faire).


  • Merci Alf de ta réponse claire et rapide enfaà®te j'ai écrit ma présentation une fois la question posée, elle est déjà  posté enfaite.


    J'ai été surpris d'avoir une réponse si rapide, je pensais avoir le temps de me présenter avant qu'on me réponde ^^

     


    Coredata oui, c'est aussi ce que je me disais ! 




  • ... Tu peux plutôt utiliser un delegate, ce sera plus adapté pour une variable...  




     


    L'objectif de la délégation n'est pas de passer une variable d'objet a un autre, mais plutôt de déléguer une tâche d'un objet vers un autre objet helper, et biensur on lui passant ce qu'il lui faut pour bien faire sa tache.

  • Oui, Céroce, j'ai déjà  vu qu'il était possible de le faire d'une vue à  l'autre conjointement liée par un serge, je sais même comment le faire mais justement je voulais savoir si il était directement possible de passer la variable de la vue 3 à  6 sans la faire passée par chaque vue intermédiaire. Enfin si j'ai bien compris...


     


    J'ai pas bien compris samir2303, cela veut dire que utiliser delegate n'est pas la bonne méthode à  arborer ou oui mais à  condition d'utiliser les bons paramètres ?




  • L'objectif de la délégation n'est pas de passer une variable d'objet a un autre, mais plutôt de déléguer une tâche d'un objet vers un autre objet helper, et biensur on lui passant ce qu'il lui faut pour bien faire sa tache.




     


    C'est vrai que ce n'est pas l'objectif premier, mais çà  te permet de passer les objet dont tu peux avoir besoin dans cette autre vue. Même si c'est aussi un marteau pour écraser une mouche...

  • MontetMontet Membre
    septembre 2013 modifié #8

    Mmmh encore un marteau donc :S 


    Il existe donc pas une méthode "tapette à  mouche" des plus raffinées ? :D


     


    http://forum.cocoacafe.fr/topic/6373-communications-inter-controller/ <- il y avait bien ce topique qui parlait semblerait-il de la même chose cependant le lien présenté est mort :/ ça m'avance pas trop


  • AliGatorAliGator Membre, Modérateur
    Je rejoins Céroce.

    Si tu as bien découpé ton application suivant le principe du MVC, tu n'as qu'à  mettre ta valeur dans ton Modèle, c'est ce qui semble le plus logique.

    Comme tous les controlleurs ont certainement besoin du modèle (vu que tu es MVC, n'est ce pas ?) et que tu as certainement déjà  prévu une manière pour ces derniers d'accéder au modèle (passage proche en proche, communication via @protocol du genre datasource ou delegate, sharedInstance, ...), tu auras déjà  tout ce qu'il faut.
  • CéroceCéroce Membre, Modérateur


    Oui, Céroce, j'ai déjà  vu qu'il était possible de le faire d'une vue à  l'autre conjointement liée par un serge, je sais même comment le faire mais justement je voulais savoir si il était directement possible de passer la variable de la vue 3 à  6 sans la faire passée par chaque vue intermédiaire. Enfin si j'ai bien compris...




    Tu as bien compris, mais je dirais que si tu as six vues qui se suivent, tu as déjà  un problème de conception. Six niveaux hiérarchiques, sur une appli iPhone ?!

  • MontetMontet Membre
    septembre 2013 modifié #11

    Au début j'avais une seule classe pour toute mes vues ensuite à  cause d'habitude sur vb, je me suis dit que ce serait peut-être préférable en terme de ressources de fragmenter mon code, de manière à  ce que chaque vue ait sa classe propre(j'entends par la un fichier .m et .h).


    Problème de conception peut-être, vu que j'ai pas vraiment effectué un projet sous forme, analyse, conception, réalisation, car ici je voulais juste faire une application pour ne faire déjà  une idée. T'entends par là  problème de conception car je devais utiliser une vue pour afficher/masquer des contrôles au lieu de passer à  la suivante ?


    Mon idée de l'application était la suivante, elle a pour but de récrée l'expérience physique d'érathostène est dans le future d'autre expérience y seront ajouté. Donc un application qui permettra à  des étudiants de réaliser des TP de physique.


     


    J'avais segmenter dans ma tête le code de manière suivante :


     


    1) Ecran de titre choix de l'expérience (ici de future contrôle permettrons d'accéder à  d'autre expérience)


    2) Ecran de théorie, lecture dans une textview et un bouton suivant


    3) Ecran qui permet de sélectionner un pseudo (qui permettra de mettre un nom sur le données qui seront envoyé sur parse)


    4) Ecran de localisation, affiche la longitude et latitude ainsi qu'une carte qui affiche la position (la longitude et la latitude seront envoyé aussi sur parse)


    5) Ecran de permet de déterminer l'angle solaire actuel (angle sera envoyé sur parse)


    6) Ecran de synthèse qui affiche toute les informations qui seront envoyé sur parse + envoi 


    7) Sélection de données d'un autre utilisateur sur parse


    8) Calcule de la distance séparant les deux utilisateur grâce à  l'angle solaire, démonstration et retour à  la page de choix de l'expérience


     


    (Je suis conscient qu'il serait plus pertinent de faire le choix du pseudo une seule fois pour toute les expérience mais la n'est pas la question)


  • Je viens de trouver une solution peut-être pas la meilleure mais elle marche !

    J'ai utilisé l'appdelegate ! Je devais avoir la tête dans les choux ! Pourquoi j'y avais pas songé ...


    Pour ceux qui chercherait comme moi je leur donne la procédure toute conne :


    1)Déclarer sa variable dans appdelegate.h


    2) importer appdelegate.h dans la vue voulu


    3) utiliser la méthode : AppDelegate * shareDelegate = [[UIApplication sharedApplication] delegate];


    shareDelegate.nom_de_votre_variable = 


     


    Lien qui peut-être utile pour comprendre la couche modèle et appdelegate
    http://www.ltm.fr/3-3-ios-comprendre-l-appdelegate/


  • AliGatorAliGator Membre, Modérateur
    En effet, loin d'être le pattern le plus adéquat (on en a déjà  parlé plein de fois). Quitte à  partir sur une solution de ce genre, il est limite préférable de dédier un singleton pour les accès à  ton modèle partagé, plutôt que d'utiliser le UIAppDelegate qui n'est pas fait pour...
    Là  tu ne pars pas vers des patterns et solutions les plus propres et les mieux adaptées. Certes ça marche mais c'est un peu brouillon et pas une architecture très clean...
  • CéroceCéroce Membre, Modérateur

    Au début j'avais une seule classe pour toute mes vues ensuite à  cause d'habitude sur vb, je me suis dit que ce serait peut-être préférable en terme de ressources de fragmenter mon code, de manière à  ce que chaque vue ait sa classe propre(j'entends par la un fichier .m et .h).

    Tu confonds vue (classe héritant de UIView) et View Controller (classe héritant de UIViewController), mais dans l'idée, c'est bien ça qu'il faut: un View Controller par écran.

    T'entends par là  problème de conception car je devais utiliser une vue pour afficher/masquer des contrôles au lieu de passer à  la suivante ?

    Non, laisse béton, c'est moi qui n'ai pas regardé le storyboard que tu avais mis en copie d'écran au début.
    Ton approche est bonne si tu veux que tes écrans s'enchaà®nent.

    Mais note toutefois que cette approche de faire des étapes est souvent mauvaise: c'est à  l'utilisateur de prendre l'initiative. Après, ça peut aussi se discuter dans certains cas où il faut justement guider l'utilisateur. Je trouve que dans ton cas, ça se justifie partiellement.

    Je viens de trouver une solution peut-être pas la meilleure mais elle marche !

    Cette approche, beaucoup utilisée sur iPhone est de la merde: ça crée un dépendance de tous les View Controllers sur l'App Delegate.

    Utiliser un Singleton pour conserver le modèle est une approche un poil meilleure. Seulement un poil, parce qu'elle ressemble beaucoup à  une variable globale (tout le monde accède à  tout).

    Qu'est-ce qui te dérange de passer le modèle de VC en VC ?
  • MontetMontet Membre
    septembre 2013 modifié #15

    Je vais m'informer d'avantage sur les singleton alors ! Merci de l'aiguillage !


    Pour être sûr singleton serait la meilleure solution ou il y a encore une manière plus propre de le faire ?


    Tant qu'à  faire les choses je préfères prendre les bonnes habitudes dès le départ ^^


    (Mais en tout cas déjà  merci bien de m'avoir mi un peu au claire, j'étais à  l'ouest... )


     


    Ce qui me dérange un peu dans l'approche VC par VC c'est que certaine vue n'auront pas besoin des informations qu'elles passent .. et ça fait pas mal de code pour je trouvais pas très directe comme manière de procéder mais si un pro comme toi me le conseil, je m'y plierais, y a surement expérience et raison qui parle !


  • Au lieu de passer par l'appDelegate ce qui serait une énorme bourde niveau archi crée un modèle...


     


    J'entend par la :


    -un objet qui représente ce que tu dois stocker/gérer


    -un objet qui permet de le stocker vers ce que tu veux base/fichier etc...


    -un objet qui te donne accès au données


     


    A partir de la tu auras tout ce qu'il faut pour gérer tes données a transmettre.


     


    Après c'est peut être gros pour une simple variable mais si tu es amené à  gérer plus de données ça sera mieux.


     


    Pour ton appli le plus simple serais de passer les variables qu'il te faut de vue en vue, je pense.


     


    Ali me tape pas trop fort si j'ai dis des bêtise :)


  • Mais j'ai pas directement déclaré mes objets dans l'appdelegate, je suis pas aussi fou que ça.


    J'ai crée des variables(déclaré dans l'appdelegate) qui prennent la valeur des objets qui sont déclarer dans leur propre modèle de vue (leur fichier .h respectif).


  • AliGatorAliGator Membre, Modérateur
    septembre 2013 modifié #18

    Mais j'ai pas directement déclaré mes objets dans l'appdelegate, je suis pas aussi fou que ça.
    J'ai crée des variables(déclaré dans l'appdelegate) qui prennent la valeur des objets qui sont déclarer dans leur propre modèle de vue (leur fichier .h respectif).

    Bah c'est tout aussi dégueulasse, au final tu utilises le AppDelegate pour un truc pour lequel il n'est pas fait pour (centraliser des infos), alors que le AppDelegate est là  pour que la UIApplication lui délègue des actions concernant l'application (quoi faire quand l'appli se lance, quand elle passe en background, ...).

    Pour être sûr singleton serait la meilleure solution ou il y a encore une manière plus propre de le faire ?

    Encore une fois je rejoins Céroce (as-tu lu ses réponses ?) qui a déjà  dit qu'un singleton est un peu mieux qu'utiliser le AppDelegate... mais que la meilleure solution et plus logique est quand même le passage de proche en proche, pour que chaque VC soit dépendant du modèle et non d'un objet central et pour éviter une trop grande adhérence entre toutes les classes de ton application.
    Mais bon il a beau insister et moi aussi sur cette solution, tu as l'air d'être têtu et continuer à  nous demander s'il n'y a pas mieux que l'AppDelegate ou le singleton...
  • ça a le mérite d'être clair ... J'ai pas dit que c'était propre d'ailleurs, je vais chercher un meilleur moyen




  • Ce qui me dérange un peu dans l'approche VC par VC c'est que certaine vue n'auront pas besoin des informations qu'elles passent .. et ça fait pas mal de code pour je trouvais pas très directe comme manière de procéder mais si un pro comme toi me le conseil, je m'y plierais, y a surement expérience et raison qui parle !




     


    Il y a sans doute un problème de logique dans le design de l'application. Les VC s'enchaà®nent les uns après les autres mais n'ont pas toujours besoin des données précédentes, cela indique que l'enchaà®nement n'est pas logique.


    Comme te l'a indiqué Ceroce, c'est à  l'utilisateur de choisir dans quel ordre il veut saisir les données, pas à  l'application de lui imposer cet ordre. Sauf bien sûr s'il y a une logique impérative.


     


    Ce qui te gêne par exemple, c'est le pseudo saisi à  l'écran 3 qui n'est plus utilisé jusqu'à  l'écran 6.


     


    Solution 1 : Sur un mobile, il ne faut pas obliger l'utilisateur à  saisir son pseudo sans arrêt. Une fois suffit et il doit être enregistré dans les UserDefaults. Il n'y a pas à  prévoir cette saisie dans l'enchaà®nement des écrans, il faut simplement prévoir d'afficher une vue modale à  la demande de l'utilisateur et/ou juste avant le dernier écran si le pseudo n'a jamais été saisi.


     


    Solution 2 : un contrôleur des contrôleurs (genre contrôleur de navigation) qui orchestre l'affichage des écrans et passe aux contrôleurs juste les informations dont ils ont besoin.

Connectez-vous ou Inscrivez-vous pour répondre.