web-dev-qa-db-fra.com

Xcode modifie le storyboard non modifié et les fichiers XIB

Les storyboards sont plutôt une douleur royale du point de vue du flux de travail git lorsque plusieurs personnes y collaborent. Par exemple, le XML du fichier .storyboard a les attributs toolsVersion et systemVersion des balises <document> De départ modifiés par la configuration que le manipulateur de fichier le plus récent exécute. La synchronisation des versions Xcode de tout le monde semble aider précisément avec toolsVersion, mais systemVersion change quoi qu'il arrive, selon la version spécifique de Mac et/ou OS X que le développeur exécute.

C'est idiot, mais surtout inoffensif. Ce qui nous inquiète cependant, c'est qu'à d'autres moments, d'autres modifications sont automatiquement apportées au storyboard simplement en les ouvrant après un git pull. Autrement dit, Alice apporte des modifications à un storyboard, les valide et les pousse vers le référentiel. Bob tire ensuite les modifications d'Alice et ouvre le storyboard pour apporter d'autres modifications. Au moment où il ouvre le storyboard, l'icône du fichier passe immédiatement à un état modifié mais non enregistré, et un git status Indique qu'un nombre quelconque de changements étranges se sont produits. Tout cela sans que Bob n'ait rien changé ou enregistré le fichier lui-même.

Le changement automatisé le plus courant que nous constatons est la disparition ou la réapparition de toute la hiérarchie des balises <classes> Vers la fin d'un fichier de storyboard. Nous n'avons pas compris ce qui cause cela. Nous pouvons avoir plusieurs versions localisées d'un storyboard dans divers répertoires .lproj, et lors de leur ouverture dans Interface Builder, la hiérarchie des classes peut être spontanément supprimée de certains et ajoutée à d'autres, ou laissée seule dans certains. Cela provoque beaucoup de bruit dans git diff, Mais cela ne casse en fait aucune fonctionnalité. Nous ajoutons souvent de manière sélective les modifications réelles que nous avons apportées à l'index de git, nous les validons, puis nous rejetons simplement les modifications spontanées et absurdes <classes>. Il s'agit de garder les engagements petits et agréables, comme ils devraient l'être. Finalement, cependant, cela devient trop compliqué car Xcode continue de refaire les modifications, et quelqu'un les engage à nouveau avec d'autres choses ... ce qui est bien jusqu'à ce que le Xcode de quelqu'un d'autre décide de vouloir les changer de nouveau sans raison apparente. (Notre historique de commit a beaucoup de jurons à ce sujet.)

Quelqu'un d'autre voit-il ce comportement? S'agit-il d'un bogue Xcode ou d'un problème de configuration sur un ou plusieurs de nos Mac développeurs? Nous avons vu un comportement similaire lors de la collaboration avec des fichiers XIB, mais les storyboards semblent plus sensibles à cela.

128
JK Laiho

Ce n'est pas un bug, c'est une conséquence de la façon dont Xcode traite les fichiers de storyboard. J'écris un programme de diff et de fusion pour les fichiers de storyboard (lien GitHub) et j'ai passé des heures à analyser la logique des fichiers de storyboard et comment Xcode la traite. Voici ce que j'ai découvert:

  • Pourquoi des changements étranges se produisent-ils dans les fichiers de storyboard? Xcode utilise l'API NSXML pour analyser les fichiers de storyboard dans une structure d'arborescence logique basée sur NSSet. Lorsque Xcode doit écrire des modifications, il crée un NSXMLDocument basé sur l'arborescence logique, efface le fichier de storyboard et appelle XMLDataWithOptions: pour remplir à nouveau le fichier. Étant donné que les ensembles ne préservent pas l'ordre de leurs éléments, même la moindre modification peut modifier l'intégralité du fichier XML du storyboard.

  • Pourquoi la balise de classe disparaît ou réapparaît au hasard? Le <class> la section n'est rien de plus qu'un cache Xcode interne. Xcode l'utilise pour mettre en cache les informations sur les classes. Le cache change souvent. Des éléments sont ajoutés lorsque la classe .h/.m les fichiers sont ouverts et supprimés lorsque Xcode soupçonne qu'ils sont obsolètes (au moins les anciens Xcodes se comportent comme ça). Lorsque vous enregistrez le storyboard, la version actuelle du cache est sauvegardée, c'est pourquoi le <class> la section change souvent, voire disparaît.

Je n'ai pas procédé à une ingénierie inverse de Xcode; J'ai fait ces observations en expérimentant des fichiers Xcode et storyboard. Néanmoins, je suis presque sûr à 100% que cela fonctionne de cette façon.

Conclusions :

  • La section de cache est sans importance; vous pouvez ignorer en toute sécurité tout changement.
  • Contrairement à ce que vous pouvez trouver sur tous les forums, la fusion des fichiers de storyboards n'est pas une tâche compliquée. Par exemple, supposons que vous avez modifié MyController1 afficher le contrôleur dans un document de storyboard. Ouvrez le fichier de storyboard et trouvez quelque chose comme ceci <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>. Vous pouvez valider en toute sécurité uniquement les modifications dans cette section et ignorer tout le reste. Si vous avez modifié des séquences ou des contraintes, validez également tout ce qui a “ory-XY-OBM” à l'intérieur. Simple!
78
Marcin Olawski

Il s'agit d'un bug dans XCode 4.5+, j'espère qu'il sera corrigé, et oui c'est un PITA.

Voici le bug complet chez Apple

Comment éviter les modifications gratuites de Xcode aux fichiers de storyboard?

17
deleted_user

Ce problème peut être quelque peu atténué par une utilisation extrêmement judicieuse de git add -p sur l'un des fichiers générés par Xcode, y compris les storyboards, les XIB, les modèles Core Data et les fichiers de projet, qui souffrent tous de modifications transitoires similaires qui n'ont aucun impact sur l'interface/le modèle/le projet réel.

Les modifications indésirables les plus courantes que j'ai vues sur les storyboards sont les numéros de version du système (comme vous le mentionnez) et l'ajout et la suppression constants de <classes> section, dont je n'ai jamais vu l'omission causer des problèmes. Pour les XIB, c'est l'ajout et la suppression de <reference key="NSWindow"/>, qui n'est même pas une classe dans Cocoa Touch. Juste wow.

Pensez-y comme à la mer: il y a à la fois une marée haute et une marée basse. Laissez-le vous envahir.

Ahh. C'est tout.

Vous pouvez ignorer ces modifications lors de la mise en œuvre de vos modifications, réinitialiser les modifications indésirables et effectuer un commit propre.

Le seul avantage que j'ai vu avec les storyboards sur les XIB d'un point de vue technique est que Apple n'a pas encore castré FileMerge pour refuser de fusionner les storyboards en conflit. (FileMerge était capable de fusionner des XIB, mais les nouvelles versions ont cassé ça. Les gars de Thxxxx ???? !!!)

Veuillez déposer de nombreux bugs sur tous ces problèmes sur http://bugreporter.Apple.com/ ! Et n'oubliez pas de créer des entrées sur OpenRadar .

11
Phil Calvin

Lancer une autre réponse ici parce que cette situation s'est considérablement améliorée. Le XML du fichier XIB qui représente le StoryBoard a été considérablement simplifié.

J'ai également récemment mordu la balle et commencé à utiliser l'interface de Xcode to Source Control. Je suis sur la ligne de commande depuis des années et heureux là-bas, mais l'interface est agréable et vous permet de fractionner les commits, ce qui est vraiment important si vous utilisez un système de billetterie qui relie les commits.

Quoi qu'il en soit, j'ai remarqué aujourd'hui qu'il y avait un changement sur le storyboard et le diff intégré m'a montré qu'il s'agissait d'un seul attribut dans la balise de document (systemVersion). Donc ce n'est pas grave.

J'ai lu des articles où les gens disent que les SB étaient interdits dans leurs équipes en raison de problèmes de fusion. Folie totale. Ils sont tellement incroyables, surtout maintenant qu'ils ont une mise en page automatique intelligente intégrée, vous manquez vraiment si vous ne les utilisez pas.

6
Rob

Il est utile de savoir pourquoi cette folie est en train de se produire, mais pour ceux qui croient en la conservation de leurs projets sans avertissements et qui veulent juste un rapide et sale pour remettre leurs projets à un état sain:

  1. Ne commettez rien avant d'avoir reçu des instructions explicites.

  2. Ouvrez Xcode et créez un nouveau storyboard (Commande + N> iOS> Interface utilisateur> Storyboard). Je suppose que vous l'appelez le nom par défaut de Storyboard.storyboard.

  3. Ouvrez le storyboard que Xcode a violé. Je suppose que c'est Base.lproj/Main.storyboard.

  4. Sélectionnez et copiez tout sur le storyboard (Commande + A puis Commande + C).

  5. Ouvrir Storyboard.storyboard.

  6. Copiez et collez tout dans Storyboard.storyboard.

  7. Fermez Xcode.

  8. Ouvrez un terminal et modifiez les répertoires dans votre référentiel.

  9. Remplacer Main.storyboard avec Storyboard.storyboard (mv Storyboard.storyboard Base.lproj/Main.storyboard).

  10. git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."

  11. Ignorer les modifications apportées à project.pbxproj via git checkout -- project.pbxproj. Si vous git diff le fichier, vous verrez qu'il vient d'ajouter des informations sur notre storyboard temporaire (qui n'existe plus).

  12. Ouvrez Xcode back up et voyez que les avertissements ont disparu.

  13. Respirer.

3
Kayce Basques