Xcode ändert unveränderte Storyboard- und XIB-Dateien


132

Storyboards sind aus Sicht des Git-Workflows eher ein königlicher Schmerz, wenn mehrere Personen an ihnen zusammenarbeiten. Beispielsweise werden für das XML in der .storyboard-Datei die Start- <document>Tags toolsVersionund systemVersionAttribute geändert, je nachdem, welche Konfiguration der neueste Dateimanipulator gerade ausführt . Die genaue Synchronisierung aller Xcode-Versionen scheint hilfreich zu sein toolsVersion, systemVersionändert sich jedoch unabhängig von der jeweiligen Mac- und / oder OS X-Version, die der Entwickler ausführt.

Das ist idiotisch, aber meistens harmlos. Was uns jedoch beunruhigt, ist, dass zu anderen Zeiten einige andere Änderungen automatisch am Storyboard vorgenommen werden, indem sie nach a geöffnet werden git pull. Das heißt, Alice nimmt Änderungen an einem Storyboard vor, schreibt sie fest und schiebt sie in das Repository. Bob zieht dann Alices Änderungen und öffnet das Storyboard, um weitere Änderungen vorzunehmen. Sobald er das Storyboard öffnet, wechselt das Dateisymbol sofort in einen geänderten, aber nicht gespeicherten Zustand und git statuszeigt an, dass eine beliebige Anzahl seltsamer Änderungen aufgetreten ist. All dies, ohne dass Bob etwas geändert oder die Datei selbst gespeichert hat.

Die häufigste automatisierte Änderung ist das Verschwinden oder Wiedererscheinen der gesamten <classes>Tag-Hierarchie am Ende einer Storyboard-Datei. Wir haben nicht herausgefunden, was dies verursacht. Möglicherweise befinden sich mehrere lokalisierte Versionen eines Storyboards in verschiedenen .lproj-Verzeichnissen. Wenn Sie diese in Interface Builder öffnen, wird die Klassenhierarchie möglicherweise spontan von einigen entfernt und in andere eingefügt oder in einigen allein gelassen. Dies verursacht viel Rauschen git diff, beeinträchtigt jedoch keine Funktionalität. Wir werden oft selektiv die tatsächlichen Änderungen, die wir vorgenommen haben, in den git-Index einfügen, diese festschreiben und dann einfach das spontane, unsinnige verwerfen<classes>Änderungen. Dies dient dazu, die Commits klein und nett zu halten, wie sie sein sollten. Irgendwann wird es jedoch einfach zu viel, um sich damit zu beschäftigen, da Xcode die Änderungen immer wieder wiederholt und jemand sie zusammen mit einigen anderen Dingen erneut zusagt ... was in Ordnung ist, bis der Xcode eines anderen beschließt, sie für Nein zurück zu ändern ersichtlichen Grund. (Unsere Commit-Geschichte hat viel Schwur darüber.)

Hat jemand anderes dieses Verhalten gesehen? Ist dies ein Xcode-Fehler oder ein Konfigurationsproblem auf einem oder mehreren unserer Entwickler-Macs? Wir haben bei der Zusammenarbeit mit XIB-Dateien ein ähnliches Verhalten festgestellt, aber Storyboards scheinen dafür anfälliger zu sein.


In der Tat laufen die Xcode-Projekte und Git nicht sehr gut zusammen. Ich glaube nicht, dass Sie dieses Durcheinander auf andere Weise vermeiden können, als die unnötigen Änderungen zu verwerfen - das sind fast immer die Änderungen der Projektdateien für mich und andere XML-Dateien. Ich bin sicher, dass ich sie nicht geändert habe. Ich werde mich freuen, wenn es irgendeine "Lösung" gibt. Ich mag Perforce für die bequeme Sperrfunktion, die es Xcode nicht erlaubt, sich zu stark zu ändern. Dies kann wahrscheinlich manuell für die Dateien erfolgen, die Sie nicht ändern, sondern nur überprüfen möchten.
A-Live

3
Es lohnt sich nicht, Storyboards mit Git oder irgendetwas anderem zu verwenden. Sie sind nicht dafür ausgelegt, freundlich zu sein. Wir haben aufgegeben und sind mit .xib gegangen, was auch nicht so toll ist, aber zumindest granular.
Ahwulf

Wir haben festgestellt, dass Storyboards für eine ganze Reihe von Dingen ziemlich ordentlich sind, obwohl es oft notwendig ist, sie mit XIBs zu mischen. Sollte dieser Fehler jemals behoben werden, würden wir die meiste Zeit gerne mit ihnen zusammenarbeiten.
JK Laiho

Ich muss nur Ahwulfs Kommentar kommentieren: Was in aller Welt meinst du damit, dass sie nicht freundlich sind? Es handelt sich um XML- / Textdateien, die so festschreibungsfreundlich wie möglich sind. Und ich hatte kein Problem mit dem Storyboard und einem Versionsverwaltungssystem. Das einzige Problem ist natürlich, dass xcode manchmal das <classes> -Tag löscht und es später liest, aber Sie können dies leicht sehen, wenn Sie sich die Änderungen mit ansehen eine Git-GUI oder ein Git-P oder ein Äquivalent für welche DVDs. Ich habe dies noch nie mit der .pbxproj-Datei als Fyi erlebt.
Mgrandi

Ich kann nicht verstehen, warum xcode die Klassenblöcke in das Storyboard einfügt, wenn er diese Blöcke nur durch Lesen der Klassendateien generieren kann. sind sie eine Art "Cache"? Wenn ja, sollten sie in eine classes.cache-Datei eingefügt werden, damit wir sie von der Versionierung ausschließen können ...
hariseldon78

Antworten:


78

Dies ist kein Fehler, sondern eine Folge der Verarbeitung von Storyboard-Dateien durch Xcode. Ich schreibe ein Diff- und Merge-Programm für Storyboard-Dateien (GitHub-Link) und habe Stunden damit verbracht, die Logik der Storyboard-Dateien und deren Verarbeitung durch Xcode zu analysieren. Folgendes habe ich entdeckt:

  • Warum treten seltsame Änderungen in Storyboard-Dateien auf? Xcode verwendet die NSXML-API, um Storyboard-Dateien in eine NSSetlogische Baumstruktur zu analysieren . Wenn Xcode Änderungen schreiben muss, erstellt es eine NSXMLDocumentbasierend auf der logischen Baumstruktur, löscht die Storyboard-Datei und ruft XMLDataWithOptions:auf, um die Datei erneut zu füllen. Da Sets die Reihenfolge ihrer Elemente nicht beibehalten, kann bereits die geringste Änderung die gesamte Storyboard-XML-Datei ändern.

  • Warum verschwindet das Klassen-Tag oder erscheint zufällig wieder? Der <class>Abschnitt ist nichts weiter als ein interner Xcode-Cache. Xcode verwendet es, um Informationen über Klassen zwischenzuspeichern. Der Cache ändert sich häufig. Elemente werden hinzugefügt, wenn Klassendateien .h/.mgeöffnet und entfernt werden, wenn Xcode den Verdacht hat, dass sie veraltet sind (zumindest ältere Xcodes verhalten sich so). Wenn Sie das Storyboard speichern, wird die aktuelle Version des Caches ausgegeben, weshalb sich der <class>Abschnitt häufig ändert oder sogar verschwindet.

Ich habe Xcode nicht rückentwickelt. Ich habe diese Beobachtungen gemacht, indem ich mit Xcode- und Storyboard-Dateien experimentiert habe. Trotzdem bin ich mir fast zu 100% sicher, dass es so funktioniert.

Schlussfolgerungen :

  • Der Cache-Abschnitt ist unwichtig. Sie können jede Änderung daran ignorieren.
  • Im Gegensatz zu allen Foren ist das Zusammenführen von Storyboard-Dateien keine komplizierte Aufgabe. Angenommen, Sie haben den MyController1View Controller in einem Storyboard-Dokument geändert . Öffnen Sie die Storyboard-Datei und suchen Sie so etwas <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>. Sie können sicher nur Änderungen in diesem Abschnitt festschreiben und alles andere ignorieren. Wenn Sie Segmente oder Einschränkungen geändert haben, legen Sie auch alles fest, was darin enthalten ist “ory-XY-OBM”. Einfach!

9
Gibt es ein Update für das xcode diff / merge Tool? Klingt so, als wäre es für diese Community sehr nützlich.
Tony

1
Sie können die App von meiner Webseite erhalten (siehe Profil). Die App ist 100% kostenlos.
Marcin Olawski

1
Für mich, Storyboards so weit wie möglich zu teilen == mit XIBs. Wenn Sie alles in Scheiben schneiden möchten, ist es einfacher und besser, XIBs zu verwenden
Marcin Olawski

7
"Ich habe Xcode nicht rückentwickelt. Ich habe diese Beobachtungen gemacht, indem ich mit Xcode- und Storyboard-Dateien experimentiert habe." Das ist (flaches) Reverse Engineering und es ist cool . :-)
Constantino Tsarouhas

13
"Dies ist kein Fehler, dies ist eine Folge davon, wie Xcode Storyboard-Dateien verarbeitet." Respektvoll erklärt oder rationalisiert die zweite Hälfte dieses Satzes in keiner Weise die erste. Ich würde es ändern zu: "Dies ist ein Fehler. Es ist eine [n leider ungelöste und höchst ärgerliche] Folge davon, wie XCode .xib-Dateien verarbeitet." Von XCode 5.x bis 6.2 (heute 150311) .xib-Dateien, die in keiner Weise vom Entwickler geändert wurden und lediglich in IB angezeigt werden, unterliegen unbegründeten XML-Änderungen. Dies ist ein schwerwiegender Fehler, der sich auf die Produktivität auswirkt. Antworten wie "NBD, nur mit Brocken in Git" lassen mich sprachlos.
zweiwöchentlich

18

Dies ist ein Fehler in XCode 4.5+, ich hoffe, er wird behoben, und ja, es ist eine PITA.

Hier ist der vollständige Fehler bei Apple

Wie vermeide ich kostenlose Xcode-Änderungen an Storyboard-Dateien?


1
Gleiches in 4.6. Vielleicht ist es kein Fehler.
Thromordyn

4.6.3 hat es noch. Ich kann nicht sagen, dass Storyboard / Xibs jemals gut funktioniert haben
Houbysoft

1
"Es ist kein Fehler, es ist eine Funktion": -S
MrTJ

Es gibt keine Beweise dafür, dass dies ein Fehler ist - ein Ärger ja, aber es könnte sein, wie Xcode Sachen macht
Thomas Watson

1
7.0.1 hat daran keine Änderungen vorgenommen.
Andris Zalitis

11

Dieses Problem kann durch eine äußerst umsichtige Verwendung von git add -pgenerierten Xcode-Dateien, einschließlich Storyboards, XIBs, Core Data-Modellen und Projektdateien, die alle unter ähnlichen vorübergehenden Änderungen leiden, die keine Auswirkungen auf die tatsächliche Schnittstelle / das tatsächliche Modell / haben , etwas gemildert werden. Projekt.

Die häufigsten Junk-Änderungen, die ich auf Storyboards gesehen habe, sind die Versionsnummern des Systems (wie Sie bereits erwähnt haben) und das ständige Hinzufügen und Entfernen des <classes>Abschnitts, dessen Auslassung ich noch nie gesehen habe, verursacht Probleme. Für XIBs ist es das Hinzufügen und Entfernen von <reference key="NSWindow"/>, was in Cocoa Touch nicht einmal eine Klasse ist. Einfach wow.

Stellen Sie es sich wie das Meer vor: Es gibt sowohl Flut als auch Ebbe. Lass es dich überfluten.

Ahh. Das ist es.

Sie können diese Änderungen ignorieren, wenn Sie Ihre Änderungen bereitstellen, die Junk-Änderungen zurücksetzen und ein sauberes Commit durchführen.

Der einzige Vorteil, den ich aus technischer Sicht bei Storyboards gegenüber XIBs gesehen habe, ist, dass Apple FileMerge noch nicht kastriert hat, um das Zusammenführen von Storyboards mit Konflikten zu verweigern. (FileMerge war früher in der Lage, XIBs zusammenzuführen, aber neuere Versionen haben das kaputt gemacht. Thxxxx Leute 💜 !!!)

Bitte melden Sie viele Fehler zu all diesen Problemen unter http://bugreporter.apple.com/ an ! Und vergessen Sie nicht, Einträge in OpenRadar zu erstellen .


6

Wir werfen hier eine andere Antwort auf, weil sich diese Situation stark verbessert hat. Das XML für die XIB-Datei, die das StoryBoard darstellt, wurde erheblich vereinfacht.

Ich habe auch kürzlich die Kugel gebissen und begonnen, die Schnittstelle in Xcode zur Quellcodeverwaltung zu verwenden. Ich bin seit Jahren in der Befehlszeile und dort glücklich, aber die Benutzeroberfläche ist nett und ermöglicht das Aufteilen von Commits. Dies ist sehr wichtig, wenn Sie ein Ticketing-System verwenden, das mit Commits verknüpft ist.

Wie auch immer, ich habe heute bemerkt, dass es eine Änderung im Storyboard gab und das eingebaute Diff zeigte mir, dass es sich um ein einzelnes Attribut im Dokument-Tag (systemVersion) handelt. Also keine große Sache.

Ich habe Artikel gelesen, in denen Leute sagen, dass SBs in ihren Teams wegen Zusammenführungsproblemen verboten waren. Totaler Wahnsinn. Sie sind so erstaunlich, besonders jetzt, wo sie ein intelligentes Autolayout haben, das Sie wirklich verpassen, wenn Sie sie nicht verwenden.


3

Es ist hilfreich zu wissen, warum dieser Wahnsinn passiert, aber für diejenigen, die daran glauben, ihre Projekte frei von Warnungen zu halten und nur schnell und schmutzig wollen, um ihre Projekte wieder in einen gesunden Zustand zu bringen:

  1. Legen Sie nichts fest, bis Sie ausdrücklich dazu aufgefordert werden.

  2. Öffnen Sie Xcode und erstellen Sie ein neues Storyboard (Befehl + N> iOS> Benutzeroberfläche> Storyboard). Ich gehe davon aus, dass Sie es den Standardnamen von nennen Storyboard.storyboard.

  3. Öffnen Sie das Storyboard, gegen das Xcode verstoßen hat. Ich gehe davon aus, dass dies der Fall ist Base.lproj/Main.storyboard.

  4. Wählen Sie alles im Storyboard aus und kopieren Sie es (Befehl + A, dann Befehl + C).

  5. Öffnen Storyboard.storyboard.

  6. Kopieren Sie alles und fügen Sie es ein Storyboard.storyboard.

  7. Schließen Sie Xcode.

  8. Öffnen Sie ein Terminal und ändern Sie die Verzeichnisse in Ihr Repository.

  9. Ersetzen Sie Main.storyboarddurch Storyboard.storyboard( mv Storyboard.storyboard Base.lproj/Main.storyboard).

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

  11. Ignorieren Sie die Änderungen an project.pbxprojvia git checkout -- project.pbxproj. Wenn Sie git diffdie Datei verwenden, werden Sie feststellen, dass gerade Informationen zu unserem temporären Storyboard hinzugefügt wurden (das nicht mehr vorhanden ist).

  12. Öffnen Sie die Xcode-Sicherung und stellen Sie sicher, dass die Warnungen verschwunden sind.

  13. Atmen.


0

Die Arbeit am selben Storyboard ist kein Problem. Die Arbeit an demselben Viewcontroller, der beim Ziehen / Zusammenführen zu Konflikten führt, ist jedoch erschreckend. Wir können es nicht wirklich vermeiden, dass wir für ein großes Team im selben Viewcontroller arbeiten.

Gut ist, dass wir meistens dieselben Viewcontroller-Konflikte beheben können, wenn wir die XML-Struktur verstehen. Ich habe es nie versäumt, diese während der Arbeit im Team zusammenzuführen. Angenommen, Sie arbeiten mit einem Viewcontroller. Ihre Ansicht ist derzeit leer. Bitte schauen Sie sich die XML-Struktur des Viewcontrollers aus der Quellcode-Option an.

Geben Sie hier die Bildbeschreibung ein

Das Storyboard ist eine XML-Datei, die durch ein Dokumenttyp-Tag begrenzt ist. Alles im Storyboard enthält in scene sceneID = tag. Das Szenen-Tag enthält alle Viewcontroller. Das ist das Grundlegende.

Jetzt haben wir der Ansicht ein UILabel und einen UIButton hinzugefügt. Stellen Sie auch das Autolayout der Elemente ein. Jetzt sieht es so aus:

Geben Sie hier die Bildbeschreibung ein

Durch Hinzufügen einer Ebene / Schaltfläche zum Ansichtscontroller wurde neuer Code in das Unteransichtstag der Ansicht eingefügt. Das Gleiche gilt für weitere Elemente oder Änderungen an der Benutzeroberfläche. Überprüfen Sie sorgfältig die Tag-Struktur, die wirklich wichtig ist, um Konflikte zu beheben.

Jetzt fügen wir dem Storyboard-Namen Homeviewcontroller einen weiteren Viewcontroller hinzu. Durch Hinzufügen eines neuen Ansichtscontrollers wird eine neue Szene unter dem Tag "Szenen" hinzugefügt. Schau dir das an:

Geben Sie hier die Bildbeschreibung ein

An diesem Punkt werden wir die Struktur zufällig ändern und die Probleme / Warnungen beobachten. Wir ändern das End-Tag des ersten Viewcontroller-Labels und speichern die Datei. Führen Sie es jetzt aus und sehen Sie sich die Warnung an. Der Fehler besagt, dass das aus Zeile 23 erstellte End-Tag nicht korrekt ist. In Zeile 23 wird angezeigt, dass Beschriftungsbeschränkungen ohne End-Tag festgelegt sind. Das ist das Problem. Jetzt setzen wir das End-Tag und erstellen das Projekt. Nach dem Festlegen des End-Tags können wir das Storyboard erfolgreich anzeigen.

Geben Sie hier die Bildbeschreibung ein

Wenn Sie vor Konflikten gewarnt werden, vergleichen Sie diese bitte mit Ihrer vorherigen Quelle und ändern Sie die Quelle. Wir entfernen den alten / redundanten Code, behalten den neuen Code mit dem richtigen Tag-Start-Ende bei und reparieren die Dinge.

[NB, ich werde die Antwort mit einigen weiteren Testfällen aktualisieren, wenn ich Zeiten bekomme]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.