Implementierung der Benutzeroberfläche in iOS: Besser, schneller und skalierbar



Vor ein paar Monaten bin ich auf Netflix auf eine sehr interessante Dokumentarserie mit dem Titel Abstract gestoßen, in der die Ergebnisse professioneller Designer aus verschiedenen Bereichen wie Architektur, Grafikdesign, Mode usw. an ihren Arbeitsplätzen untersucht werden.

Es war leicht, einige Ähnlichkeiten in der Arbeit von Designern aus anderen Bereichen mit der eines iOS-Entwicklers zu erkennen, der Benutzeroberflächen implementiert. Wenn ein Designer beispielsweise etwas erstellt, das groß genug ist, um in kleinere Teile zerlegt zu werden, ist die Verwendung einer Strategie wie " Teilen und Erobern" der Schlüssel, um sich auf kleinere Teile konzentrieren zu können, die zu einem späteren Zeitpunkt des Prozesses zusammengebaut werden .

Wenn wir ein ganzes Design in kleinere Untereinheiten aufteilen, können wir jedes Problem isoliert betrachten und alle Abhängigkeiten zwischen den Komponenten beseitigen. Das Gesamtbild muss aber auch während des gesamten Prozesses vorhanden sein, da es sonst zu Problemen kommen kann, wenn es darum geht, alles wieder zusammenzufügen.

Andererseits habe ich beim Betrachten von Abstract festgestellt, dass beim Entwurf von Objekten wie Schuhen, Bannern oder Gebäuden das endgültige Design für die Lebensdauer des Produkts festgelegt bleibt. Das Design eines Nike-Schuhs wird sich nach seiner Veröffentlichung nicht ändern und es wird keine Updates geben, sobald er im Regal im Shop ist. Manchmal bleibt ein Design auch 20 Jahre später unverändert, und das Produkt ist immer noch solide.


Nike Air Max '97 - Empire State Building (New York City)

Viele iOS-Entwickler verbringen viel Zeit damit, Schnittstellen zu erstellen, Interaktionen zu definieren und UI-Details zu polieren, um große und komplizierte Anwendungen zu erstellen. Es ist natürlich notwendig, das Gesamtbild der App als Ganzes im Auge zu behalten, aber es ist ebenso wichtig, darüber nachzudenken, wie alle kleineren Komponenten getrennt und getrennt gehalten werden können - da diese kleinen Komponenten später beim Erstellen häufig wiederverwendet werden können andere Elemente der App.


Im iOS-Team in Badoo gibt es wöchentlich Veröffentlichungen, die viele neue Funktionen, Verbesserungen und andere Änderungen enthalten, die sich auf die Benutzeroberfläche auswirken. Es ist immer unser Ziel, schnell voranzukommen und Funktionen von höchstmöglicher Qualität zu veröffentlichen. Vor einem Jahr haben wir jedoch einige Probleme in unserem Entwicklungsprozess für Benutzeroberflächen festgestellt und einen Plan zur Behebung dieser Probleme entwickelt.

Problembeschreibung


Ich werde versuchen, das Problem in nur einem Satz zu definieren:
Das iOS-Team hatte keinen klaren UI-Entwicklungsprozess.
Was bedeutete das in der Praxis? Dies bedeutete, dass die Entwicklung neuer Funktionen mit Änderungen an der Benutzeroberfläche in der iOS-App zu allen möglichen Problemen führen konnte. Hier sind die häufigsten Probleme, mit denen wir täglich konfrontiert waren:

  • Die Kommunikation mit Designern war weder klar noch effektiv. Die Designer hatten wenig Transparenz über die vorhandenen UI-Komponenten, die wir in den Apps implementiert hatten. Dies zwang sie, neue Komponenten zu erstellen, die den vorhandenen sehr ähnlich sehen.
  • Es gab keine allgemein akzeptierten Muster für die Implementierung von UI-Komponenten. Jeder Entwickler implementierte Komponenten auf unterschiedliche Weise und viele von ihnen passten nicht gut zusammen.
  • Das Duplizieren von Code führte zu erheblichen Architekturproblemen, was unter anderem zu einer zyklomatischen Komplexität führte.
  • Es war immer sehr schwierig, Änderungen für dieselbe Komponente auf die gesamte Anwendung anzuwenden.
  • Es bestand ein höheres Risiko, eine Regression in vorhandene Komponenten einzuführen, sofern deren Änderungen nicht durch die Tests abgedeckt wurden.

Es würde keinen Zauberstab geben, um diese Probleme zu lösen, weil es um Prozesse geht. Um die Art und Weise zu ändern, wie Dinge erledigt werden, müssen verschiedene Teams aufeinander abgestimmt und die vom Prozess betroffenen Personen von den Vorteilen einer neuen Arbeitsweise überzeugt werden.

"Teilen und Erobern" kann hier ein praktischer Ansatz sein, der mit kleinen Problemen beginnt, jedes Problem isoliert und dann Schritt für Schritt beginnt, eine globale Lösung zu entwickeln. In diesem Artikel werde ich erklären, wie wir es erreicht haben!

UI-Frameworks


Wir gingen das Problem von der Stiftung aus an. Das erste Problem, das behoben werden musste, war die Codeduplizierung. Wir mussten unsere Komponenten vereinheitlichen und alle an einem Ort abrufen.

Unsere Lösung bestand darin, einige Frameworks zu erstellen, die wir BadooUIKit nannten. Die Idee war, dass dies alle UI-Komponenten enthalten würde, ähnlich wie Apple es mit UIKit macht. Es enthält Klassen, die die Benutzeroberflächen einer bestimmten Anwendung darstellen (es gibt einige andere Anwendungen in unserem Unternehmen, aber dieses spezielle UIKit enthält nur Benutzeroberflächenkomponenten, die für die Badoo-App spezifisch sind).

Jede Anwendung verfügt über eine andere Farbpalette, Schriftarten, Ränder usw. Daher ist es hilfreich, ein app-spezifisches Framework zu haben, um Stylesheets für die Anwendung auch innerhalb des Frameworks hinzuzufügen.



Was passiert mit UI-Komponenten, die in verschiedenen Anwendungen gemeinsam genutzt und wiederverwendet werden können?

Zu diesem Zweck haben wir ein weiteres Framework namens Platform_UIKit erstellt. Dieses Framework enthält alle allgemeinen UI-Komponenten, die in verschiedenen Apps verwendet werden können.

Haben wir die gesamte Benutzeroberfläche sofort auf das neue Framework migriert?

Nein, das wäre eine große Aufgabe gewesen. Stattdessen haben wir beschlossen, jedes neue Teil der Benutzeroberfläche innerhalb des neuen Frameworks zu erstellen, und nur dann versucht, vorhandene Komponenten zu verschieben, wenn dies Auswirkungen auf unsere aktuelle Aufgabe hatte. In einigen Fällen kann eine Komponente viele Abhängigkeiten aufweisen und ist daher schwierig von der Hauptanwendung zum Framework zu verschieben. In diesen Fällen haben wir uns im Allgemeinen dafür entschieden, die Migrationsaufgabe separat auszuführen. Im Rahmen des ursprünglichen Plans haben wir grundlegende Elemente wie Schriftarten, Farben, Schaltflächen usw. priorisiert.

Später, als das Fundament erstellt wurde, haben wir die gesamte Benutzeroberfläche für unseren Chat ebenfalls auf ein UI-Framework migriert. Wir haben es irgendwann getan, nachdem wir die Infrastruktur eingerichtet hatten, und es hat zu einem reibungsloseren Migrationsprozess beigetragen.

Randnotiz:
Wenn Sie neugierig auf den Prozess der Erstellung einer dieser Komponenten sind, lesen Sie bitte diesen großartigen Artikel meines Kollegen Valerii Chevtaev

Eine sehr wichtige Anforderung für diese Frameworks ist, dass sie nicht von anderen Frameworks oder Klassen abhängen dürfen, bei denen es sich nicht ausschließlich um Benutzeroberflächencode handelt. Zum Beispiel importieren wir niemals Modelle aus der Hauptanwendung, Klassen auf Netzwerkebene, Statistikreportern usw.

Indem wir die Benutzeroberfläche von anderen Abhängigkeiten isolieren, machen wir die Komponenten so wiederverwendbar wie möglich:



Es ist in Ordnung, dass BadooUIKit aus Platform_UIKit importiert, aber nicht umgekehrt. Wenn Platform_UIKit von BadooUIKit abhängt, ist es aus einem einfachen Grund nicht mehr anwendungsunabhängig.



In Badoo war das Hinzufügen dieser Frameworks zu unserem Projekt nicht sehr schwierig und erfordert nicht wirklich so viel Wartung. Jedes Projekt ist anders und es ist nicht immer einfach, den richtigen Weg zum Aufbau einer Struktur zu finden, aber es ist sowohl kurz- als auch langfristig von Vorteil.

Hier sind einige der Vorteile der Verwendung von UIKit:

  • Wenn Sie die UI-Komponenten an einem Ort haben, sind sie leichter zu finden und das Projekt besser organisiert, anstatt sie über die gesamte Projektstruktur zu verteilen.
  • Durch das Freigeben von Klassen aus internen Abhängigkeiten wird die Kompilierungszeit über das gesamte Projekt verkürzt.
  • Das Entfernen von Abhängigkeiten, die nicht mit dem UI-Code zusammenhängen, erleichtert die Wiederverwendung der Komponenten und verkürzt die Kompilierungszeit.
  • Aktualisieren einer Komponente in Badoo Wenn die App auf Komponenten von BadooUIKit basiert, ist es sehr einfach, Änderungen auf die gesamte Anwendung anzuwenden.
  • Isolierte Komponenten sind viel einfacher zu testen.
  • Ein separates Framework macht es bei Bedarf in anderen Anwendungen wiederverwendbar. Erstellen Sie beispielsweise eine Anwendung, in der alle Komponenten in diesem Framework aufgelistet und dargestellt werden.

Die Galerie-Anwendung




BadooUIKit hat viele unserer Probleme gelöst, aber wir wussten, dass wir noch weiter gehen können. Es gab einige Verbesserungen, die am Prozess vorgenommen werden konnten.

Wie werden alle UI-Komponenten isoliert angezeigt? Könnten wir einen Weg finden, um UI-Komponenten zu finden und zu sehen, wie sie mit verschiedenen Codefarben aussehen würden? Könnten wir sie leicht testbar machen? Gab es eine Möglichkeit, dass die Designer einen Katalog aller vorhandenen UI-Komponenten haben konnten, die wir bereits in iOS implementiert hatten?

Da wir BadooUIKit bereits als isoliertes UI-Framework hatten, haben wir beschlossen, eine einfache eigenständige Anwendung für den internen Gebrauch zu erstellen. Wir haben die Badoo Gallery vorgestellt.

Der Zweck der Badoo Gallery ist es, Entwicklern, Designern und sogar dem Produktteam als Werkzeug zu dienen, um die UI-Komponenten auf freundliche Weise zu präsentieren. In dieser Anwendung haben wir viele verschiedene Funktionen implementiert, die die Interaktion mit den UI-Komponenten erleichtern.

Da es sich bei dieser Anwendung um ein internes Tool handelt, das nicht für die Veröffentlichung im App Store vorgesehen ist, können Sie alle Funktionen oder Tools hinzufügen, die wir für erforderlich halten. In unserem Fall haben wir die folgenden Funktionen als besonders nützlich identifiziert:

  • Komponentensuche
  • Komponentenname sortieren
  • Als Favorit markieren
  • Multi-Style-Switcher - um zu sehen, wie unsere Komponente mit verschiedenen Stylesheets aussehen würde
  • Flex
  • Ein Frame-pro-Sekunde-Viewer



Jede Komponente kann abhängig von der Benutzereingabe oder der intrinsischen Logik der Anwendung viele verschiedene Zustände haben. Ein einfacher UIButton definiert beispielsweise mehrere Status: Standard, hervorgehoben, fokussiert, ausgewählt und deaktiviert.

Neugierig? Weitere Informationen finden Sie hier .

Wir wollten auch die Möglichkeit haben, alle Kombinationen in unserer Galerie zu präsentieren. Wir tun dies in jedem spezifischen Bildschirm für jede Komponente. Natürlich können unsere eigenen Versionen von Butt andere Zustände haben als Apples UIKit-Button.



Dies ist eine Zusammenfassung der Hauptvorteile der Badoo Gallery:

  • Listet alle UI-Komponenten auf, die wir in iOS implementiert haben
  • Einfache Suche und Suche nach UI-Komponenten. Jetzt kann jeder in unserem Team oder Produktteam alle möglichen Optionen einer UI-Komponente sehen und neue Verwendungsmöglichkeiten für sie finden
  • Die Möglichkeit, bereits vorhandene Komponenten leicht zu finden, macht es viel einfacher, einen Designer davon zu überzeugen, sie wiederzuverwenden
  • Die Kompilierungszeit eines sehr kleinen Projekts wie dieser Galerie ist sehr kurz. Die Entwicklungsgeschwindigkeit des gesamten Features kann durch die Implementierung der Benutzeroberfläche in dieser Light-Anwendung verkürzt werden
  • Die Favoritenfunktion hilft uns, die Komponenten zu finden, die wir gerade implementieren
  • Das Hinzufügen externer Tools wie FPS, Multi-Brand und Flex hilft, die Qualität der im Katalog enthaltenen UI-Komponenten zu verstehen, zu verbessern und zu messen
  • Alle diese Komponenten befinden sich jetzt in einem separaten Framework und werden isoliert dargestellt. Dies macht sie leicht testbar!

Über das Testen


Die meisten der im Artikel aufgeführten anfänglichen Probleme wurden durch die Einführung der neuen Tools gelöst:



Es gab jedoch noch einige Probleme, die verbessert werden konnten, andere Fragen, die beantwortet werden mussten: Wie können wir bei Änderungen sicherstellen, dass die Benutzeroberfläche nach einigen Änderungen wie erwartet aussieht? Wie können wir vermeiden, dass andere Teile der Anwendung oder andere Komponenten beeinträchtigt werden, wenn "Unterkomponenten" geändert werden?

Eine gute Möglichkeit, Antworten auf all diese Fragen zu finden, besteht darin, den UI-Komponenten Tests hinzuzufügen. Es gibt bereits viele Dokumentationen zur Implementierung von UI-Tests in iOS. Es stehen auch viele verschiedene Tools zum Testen verschiedener Aspekte der Benutzeroberfläche einer Anwendung zur Verfügung.

In Badoo haben wir beschlossen, Snapshot-Tests mit einem der derzeit beliebtesten "Tools" für Snapshot-Tests iOSSnapshotTestCase : iOSSnapshotTestCase (früher bekannt als FBSnapshotTestCase da es ursprünglich von Facebook als Open Source erstellt und veröffentlicht wurde).

Weitere Informationen zu Snapshot-Tests und diesem speziellen Framework finden Sie unter den folgenden Links:



Wir mussten einen Weg finden, um die Komponenten zu testen, die wir bereits in BadooUIKit hatten, um mögliche Regressionen zu vermeiden und gleichzeitig die Komponenten zu ändern, die vom Rest der App verwendet werden.

Wir wollten auch den Prozess des Hinzufügens eines neuen Snapshot-Tests für eine Komponente so weit wie möglich automatisieren.

Wie weiter oben in diesem Artikel erläutert, verfügen wir auch über eine Galerieanwendung, in der alle Komponenten und alle unterschiedlichen Zustände einer einzelnen Komponente aufgelistet sind. Dies ist sehr praktisch, da die Snapshot-Tests mithilfe von Badoo Gallery als Host-Anwendung hinzugefügt werden können.

Alle in BadooUIKit implementierten UI-Komponenten werden in einer Klasse (Repository oder Speichermuster) gespeichert, die den Zugriff auf alle Komponenten ermöglicht. Dieser Speicher kann instanziiert werden, um sowohl die Liste der Komponenten in der Galerie anzuzeigen als auch über die Snapshot-Testklassen darauf zuzugreifen. Dies bedeutet, dass es nicht erforderlich ist, die Arbeit zum Instanziieren und Vorbereiten der verschiedenen Zustände jeder Komponente in der Testebene zu duplizieren, da dies bereits beim Einführen der Komponente in die Galerie-App-Oberfläche erfolgt ist.

Dies sind einige Fragen, die beim Testen von Schnappschüssen auftreten können. Gestatten Sie mir einige Antworten:

Wo werden die Schnappschussbilder gespeichert?

Wir speichern sie direkt im Git-Repository. Anfangs dachten wir, dass es die Größe des Repositorys zu stark erhöhen könnte, aber es erwies sich als nicht schlecht. In den meisten Fällen testen wir keine Vollbildschirme, sondern kleine Komponenten. Daher sind die Screenshots sehr leicht. Derzeit ist unser Screenshot-Ordner ca. 11 MB groß, was wir für akzeptabel halten.

Werden alle möglichen Auflösungen in allen möglichen Simulatoren getestet?

Nein, der Nutzen wäre nicht riesig und könnte zahlreiche Probleme verursachen, einschließlich flockiger Tests, eines schwereren Snapshot-Ordners und größerer Schwierigkeiten bei der Wartung der Testsuite. Wir haben es vorgezogen, pragmatisch zu sein und nur das Gerät zu testen, das bei unseren Benutzern am beliebtesten ist. Unser kontinuierliches Integrationssystem ist auch so eingerichtet, dass ein Simulator des gleichen Gerätemodells verwendet wird, mit dem die Schnappschüsse erstellt wurden.

Reichen Snapshot-Tests aus, um die gesamte Benutzeroberfläche abzudecken?

Das glaube ich nicht. Bei Badoo gibt es auch verschiedene Arten von Tests auf verschiedenen Ebenen der Anwendung, z. B. Funktionstests (wir verwenden Calabash- und KIF-Frameworks) und einige Integrationstests. Nach meiner Erfahrung ist es wichtig, ein ausgewogenes Verhältnis zwischen der Art der Tests und der Anzahl der Tests zu finden, die erforderlich sind, um die Anforderungen einer Anwendung zu erfüllen.

Lektionen gelernt


Natürlich hat unser Unternehmen während des Erstellungsprozesses dieser neuen Plattform viele Dinge gelernt und wir lernen immer noch mit jeder Iteration. Alle oben genannten Tools und Prozesse wurden in einem Zeitraum von etwa 12 Monaten eingeführt und entwickeln sich weiter. Bisher hat sich jeder einzelne Schritt sowohl für die Entwickler als auch für das Unternehmen als positiv erwiesen, und von Anfang an konnten wir positive Ergebnisse erzielen. Hier sind einige der Lektionen, die wir während dieses Prozesses gelernt haben:

  • Das gleichzeitige Verschieben aller vorhandenen Komponenten ist eine sehr große Aufgabe. Durch das Erstellen des Entwurfssystems und die Ermutigung des Teams, es als Teil des Entwicklungsflusses zu verwenden, wird die Anzahl der UI-Komponenten schrittweise erhöht. Durch das Verschieben einiger Komponenten in jeder Aufgabe, die einige Entwickler implementieren, wird nicht nur automatisch die Anzahl der UI-Elemente in Ihrem System erhöht, sondern auch einige Abhängigkeiten zwischen vorhandenen Elementen entsperrt und freigegeben. Dies erleichtert die Aufgabe, später immer mehr Komponenten zu bewegen.
  • Wir haben gelernt, dass Designer gerne vorhandene Komponenten wiederverwenden, aber es ist einfacher, sie zu überzeugen, wenn wir nachweisen können, dass wir bereits eine voll funktionsfähige Komponente haben, die sich sehr ähnlich wie das verhält, was sie benötigen.
  • Die Notwendigkeit, mittelfristig Zeit zu sparen, ist Realität. Wir alle wissen, dass die Kompilierungszeiten in Swift + Objective-C-Projekten derzeit nicht die besten sind. Die Badoo Gallery App ist sehr leicht und lässt sich sehr schnell kompilieren. Wir haben gelernt, dass es viel besser ist, die UI-Komponenten direkt mit der Galerie-App als Spielplatz zu implementieren und sie dann einfach aus der Hauptanwendung zu verwenden, wo die Kompilierungszeiten nicht so schnell sind.
  • Die Komponenten in einem bestimmten UIKit und einer Galerie-Anwendung zu haben, in der wir die Komponenten einfach testen können, beschleunigt den gesamten Testprozess und ermöglicht es uns, Tests einfacher zu schreiben.


Weiter gehen - Kosmos


In Badoo kümmern wir uns um alle unsere Funktionen und möchten, dass sie eine einheitliche und visuell attraktive Benutzeroberfläche haben, um unseren Benutzern die bestmögliche Benutzererfahrung bei der Nutzung aller unserer Plattformen zu bieten. Aus diesem Grund nehmen wir mit Hilfe der Design- und Produktteams globale Änderungen im gesamten Unternehmen vor und implementieren ein Designsystem namens Cosmos.



Cristiano Rastelli hat mehrere interessante Artikel geschrieben, in denen er ausführlich erklärt, wie Cosmos zum Leben erweckt wurde. Verpassen Sie sie nicht!

Danksagung


Dieses Projekt war kein Ein-Mann-Job: Das gesamte iOS-Team, einschließlich Manager, Entwickler und QAs, nahm auf die eine oder andere Weise teil. Ich muss mich bei allen bedanken, denn ich kann sagen, dass sie alle von Anfang an an Bord waren.

Dank des großartigen Designteams von Badoo, das immer bereit ist, die Extrameile zu gehen, wenn es darum geht, die Designprozesse im gesamten Unternehmen zu verbessern.

Ein besonderer Dank geht an Alexander Zimin für die zahlreichen Verbesserungen und für seine Teilnahme an so vielen Meetings zu diesem Prozess sowie für die persönliche Unterstützung bei diesem UI-Abenteuer. Auch an Alyssa Ordillano für ihre exzellenten Grafiken, die die Zugänglichkeit dieses Artikels erheblich verbessert haben.

Source: https://habr.com/ru/post/de440920/


All Articles