Was Sie wissen möchten, bevor Sie eine Anwendung für die Apple Watch schreiben: unsere Erfahrung

Eine sehr langsame Plattform erwartet Sie, der Übergang zu neuen Frameworks, das Testen mit einer speziellen Atmosphäre und Benachrichtigungen vom Betriebssystem "hey, move" eine Sekunde vor dem erzwungenen Entladen des Threads.


Ja, das ist meine haarige Hand.

Unser Zugfahrplan sieht 600.000 Menschen pro Tag vor. Und jedes Jahr mehr und mehr - über die mobile Anwendung. Wir dachten und beschlossen, eine Version für die Uhr zu machen. Das Problem war, dass wir nicht wussten, wie viele Apple Watch es auf dem russischen Markt gibt und wie viele von ihnen in elektrischen Zügen fahren. Aber auf jeden Fall war es notwendig herauszufinden, wie das geht, also haben wir Apple um Statistiken gebeten.

Seltsamerweise taten sie es nicht. Dann haben sie in jeder Hinsicht weiter geholfen, aber hier mit Statistiken gibt es direkte Probleme. Bis vor einem Jahr hatte niemand normale Daten, und selbst das Studium von Verkaufsberichten half nichts. Uhren werden auf vielfältige Weise ins „Grau“ gebracht und zunächst nicht aus unserer Region.

Warum Statistiken? Um zu verstehen, wie viele Generationen es auf dem Markt gibt. Am Ende haben wir uns entschlossen, alle Geräte zu unterstützen.


Die letzten Statistiken, die wir für 2017 kennen, sahen folgendermaßen aus:

  • 1. Generation (alle) - 57%
  • Serie 2 (alle) - 32%
  • Serie 1 (alle) - 11%

Mit Blick auf die Zukunft hatten wir drei Monate nach der Veröffentlichung im Jahr 2019 Folgendes:

  • Apple Watch Series 3 (alle) - 36%
  • Serie 4 (alle) - 31%
  • Serie 5 (alle) - 24%
  • 1. Generation (alle) - 4,5%
  • Serie 2 (alle) - 2,5%
  • Serie 1 (alle) - 2%

Bildschirmgrößenverteilung der letzten beiden Revisionen:

  • S4 groß bei 44 mm - 58%, klein 40 - 42%.
  • S5 groß - 60%, klein 40%.

Vorgängermodelle haben noch 38 mm, in der Gesamtzahl aller Installationen sind es etwas weniger als 20%, hauptsächlich aufgrund von S3. Übrigens brauchten wir Schriftarten für verschiedene Bildschirmgrößen - unsere Designer haben adaptive gemacht.

Sehr langsame Plattform


Wir scheinen also nicht sehr viele Geräte zu haben, von denen jedoch bis zu 5% (wie erwartet) sehr alt sein werden. Die ersten Stunden waren anscheinend im Allgemeinen wie ein Gerät konzipiert, das Bilder zeigt, die auf dem Telefon generiert werden. Dann erschien ein eigenes entwickeltes Betriebssystem und in späteren Revisionen auch ein Wi-Fi und eine SIM-Karte.

SIM-Karte in Russland funktioniert nicht. Vielleicht werden sich die Betreiber in diesem Jahr einig sein, aber bisher gibt es nur WLAN und Kommunikation per Telefon (die Uhr stellt über Bluetooth eine Verbindung zum iPhone her und nutzt dann die Internetverbindung).

Die Logik der Arbeit mit Netzwerk, Speicher und Festplatte ist fast dieselbe wie unter iOS.Ich meine, die Logik selbst ist üblich, die Dienste sind üblich, aber es gibt immer noch einen Hinterhalt mit Bibliotheken - tatsächlich entwickeln sich nicht viele Leute stundenlang, so dass es unter iOS / iPadOS möglicherweise keine beliebten Frameworks und Tools gibt. In unserem Fall bedeutete dies, dass der Haufen von Bibliotheken, den wir mit der üblichen Handbewegung an eine iOS-Anwendung angeschlossen hatten, aufgegeben werden musste.

Alle Uhren führen ausnahmslos sehr langsame Festplattenzugriffe durch, verglichen mit dem Lesen aus dem Speicher. Wenn Sie sich auf einem iPhone nicht wirklich darum kümmern können, wo genau sich der 40-KB-Tisch befindet, ist es auf der Uhr wichtig, ihn im Speicher zu behalten oder über die Luft zu empfangen. Das Wichtigste ist, nichts von der Festplatte zu lesen.

Je neuer die Uhr, desto schneller dreht sie sich natürlich, aber wir arbeiten tatsächlich für S3 mit Unterstützung für frühere Geräte und zusätzlichen Funktionen für S4 und S5.

Die Alpha-Version der Anwendung, die die Route nach Hause zeigte, wurde zehn Sekunden lang auf die Uhr geladen. Der MCC-Fahrplan wurde für 20 Sekunden in den 4 nächstgelegenen Zügen angezeigt. Das Problem lag im Tabellenrender - zu viele Einzelelemente. Stellen Sie sich einen modernen Browser vor, der versucht, etwas auf dem 386SX-Kern zu rendern. Wir hatten also ähnliche Probleme.

Deshalb ist sie natürlich Alpha, um mit ihr herumzustöbern. In der Beta-Phase verteilen wir die Last auf die Threads (wobei eine Funktion auf dem Weg abgefangen wird, dass beim Starten der Uhr unter watchOS 4 der Haupteinstiegspunkt nicht im Mainstream startet). Für "schwache" Stunden war die Anzahl der Zellen in der Schnittstelle begrenzt.


Jeder von ihnen wurde für etwa eine Sekunde gerendert.



Einige Optimierungen der Benutzeroberfläche selbst und flogen zu S4, und für ältere Geräte musste die Anzahl der angezeigten Züge reduziert werden.

Sie fügten oben und unten "zeige die Verstorbenen" und "zeige als nächstes" und auf den Auserwählten "zeige alle" ein. Da sich dieser Zeitplan häufig ändert, war es häufig erforderlich, ihn neu zu zeichnen: Wir sprechen von Situationen, in denen sich die Zusammensetzung der Tabelle entweder aufgrund eines abfahrenden Zuges oder aufgrund einer Änderung des Zeitplans ändert (wir zeigen Echtzeitbewegungen, dh wir wissen, wo genau die einzelnen sind Zug in der Tat, und wie es alle weiteren Stationen entlang der Strecke beeinflussen wird).

Oft gibt es Situationen, in denen die Daten eine Sekunde nach der Anforderung veraltet sind. Mit dem grundlegenden Ansatz wurde die gesamte Tabelle verdreht, dies ist die Standardmethode für iOS. Dort ist das Update in der Regel nicht wahrnehmbar. Und hier haben sie viel Mist gemacht, basierend auf der Verarbeitung des eingehenden Arrays, das zuerst die Daten analysiert, dann das Diff erstellt, dann die UI-Elemente findet, die geändert werden können, ohne den Rest zu berühren, und dann nur sie aktualisiert. Es gibt keine geeigneten Bibliotheken für eine Komplettlösung unter WatchOS, aber es gibt ein Differentiator Kit, das eine Liste darüber enthält, wie und was sich durch Indizes des Datenarrays mit Markup geändert hat. Sie haben ihren Code darum geschrieben und ihn auf alle Tabellen gesetzt. Dies führte zu einer Erhöhung der Leistungsaktualisierungen.

Im Allgemeinen werden die nächsten N Züge schnell angezeigt. Wenn Sie warten möchten, aber ein vollständiges Bild wünschen, können Sie auf "Alle anzeigen" klicken.

Wie gesagt, das Zifferblatt in der Uhr ist groß, aber langsam. Zuerst verwendeten wir einen Standardsatz von iOS-Bibliotheken, die über die Festplatte funktionierten. Wir haben den Zeitplan erhalten, ihn auf einer Festplatte aufgezeichnet, den Dienst angefordert, ihn von der Festplatte genommen und auf den Bildschirm abgewickelt. Wie sich herausstellte, müssen Sie den Cache im Speicher speichern. Und doch sind wir es gewohnt, alle Arbeitszustände des Benutzers auf der Festplatte zu speichern und von dort aus zu lesen - wir mussten nur alles aufzeichnen und speichern, was wir konnten.



Warum ist eine ständige Aufzeichnung notwendig? Denn wenn der Benutzer die Anwendung wechselt, erfolgt das Entladen fast sofort. Normalerweise haben Sie keine Zeit, etwas auf die Bremsscheibe zu schreiben. Sie müssen dies daher ständig und iterativ tun, während der Benutzer arbeitet.

Und dann nähern wir uns dem nächsten Hinterhalt.

Manische Energieeinsparung


Der Akku in der Uhr ist klein und das gesamte Betriebssystem wird geschärft, um die Stromversorgung so weit wie möglich zu erhalten. In der Praxis kann dies bedeuten, dass der Benutzer Folgendes tut:

  1. Startet das Herunterladen von etwas (z. B. einen vollständigen Zeitplan)
  2. Senkt die Hand
  3. Wartet
  4. Hebt eine Hand, um zu sehen, was geladen ist

In der Tat passiert Folgendes:

  1. Der Benutzer beginnt mit dem Herunterladen des vollständigen Zeitplans
  2. Senkt die Hand
  3. Uhren verstehen, dass sie nicht mit ihnen arbeiten und setzen den Prozess in ein Analogon von Hybernate.
  4. Der Benutzer wartet und hebt dann die Hand, um das Ergebnis anzuzeigen.
  5. Zum Zeitpunkt des Aufstiegs versteht die Uhr, dass sie weiterhin mit ihnen arbeiten, aufwachen und den Prozess aufwecken.
  6. Der Benutzer sieht den Start der Download-Anzeige.

Gleichzeitig kann dies aus Sicht des Threads entweder der richtige Zeitpunkt oder eine „sehr lange Sekunde“ sein. Wenn Sie bei Zeitüberschreitungen Code schreiben, können Sie plötzlich sogar ein Jahr abfangen, in dem eine halbe Sekunde gewartet hat. Denken Sie daher daran, dass die Zeit relativ ist.

Der Aufweckprozess droht Ihnen mit einem langen Debugging-Prozess - dort können Sie Abstürze feststellen, wenn entweder der Ort geräumt ist oder etwas anderes Interessantes passiert.

Das Einschlafen kann zu einem Entladevorgang (ohne Aufwachen) werden. Sie müssen also einige Dinge auf die Festplatte schreiben. Das Betriebssystem teilt dem Thread "Gehe zum Hintergrund" mit und ruft die entsprechende Methode auf. Normalerweise haben Sie ungefähr eine Sekunde Zeit, um schnell auszusteigen und im Hintergrund zu landen. Wenn ein Benutzer dies beim Schreiben auf eine Disc tut (was, wie ich mich erinnere, auf Geräten bis S4 höllisch langsam ist), findet die Aufnahme möglicherweise nicht statt. Dazu müssen Sie in den Modus „Wichtiger Betrieb“ wechseln und mit Hilfe mehrerer Sonderaufrufe den Thread „bewusst“ halten. Dazu benötigen Sie einen separaten Handler, der den Aufzeichnungsprozess fragt, wann er beendet wird, und dann den Thread in den Ruhezustand versetzt.

Die Architektur


Unsere erste Bewerbung im Jahr 2017 war nur eine leere Bewerbung, die den auf dem Telefon erstellten Zeitplan anzeigen konnte. Es wurde verwendet, um Daten für einen Fernzug ​​auf einer Strecke, einem Auto und einem Ort anzuzeigen.

Die moderne Version für Züge ist „erwachsen“ und autonom, dh sie kann jederzeit ohne Telefon leben. Sogar ab dem Moment der Installation (obwohl die Anwendung normalerweise über das Telefon in die Uhr gelangt und es zu diesem Zeitpunkt sehr bequem ist, die Profildaten und alle ausgewählten Routen vom Telefon zu kopieren).

Die Architektur der Uhr ist wahrscheinlich die modernste in iOS-Mustern. Redux ist kein Problem. Wir verwenden wie in der "großen" Anwendung die Zustandsmaschine. Die Standard-MVC lautet wie folgt: Es gibt ein Modell auf der einen Seite, es gibt Ansichten für dieses Modell in der Mitte des Controllers. Der Controller nimmt Daten aus dem Modell, konvertiert sie und zeigt sie auf dem Bildschirm an. In der entgegengesetzten Richtung wartet der Controller auf Ansichtsnachrichten und stellt dem Modell Daten zur Verfügung. Basierend auf diesem Muster wurden viele Arten von Architekturen erstellt.

Wir haben einen Zustand, in dem Ereignisse einfliegen und es mutieren können. Nebenwirkungen, die nützliche Arbeit leisten, können vom Staat abweichen. Aus diesen Ergebnissen fliegen Ereignisse in den Zustand. Der vollständige Status der Anwendung ist in der Geschichte gespeichert, ein solcher Punkt der Wahrheit. Der Zustand kann in Teile zerlegt und geteilt werden, speichert aber in jedem Fall den gesamten Datensatz. Die spezifische Implementierung der Architektur hängt von der Religion ab, wir haben RXFeedback.

Die Zustandsmaschine ist durch Tests sehr gut abgedeckt. Dies hat uns viel Zeit nur auf der Uhr gespart, da keine Tests innerhalb der Uhr selbst durchgeführt werden können. Dies ist kein iPhone für Sie. Hier müssen Sie dies tun:

  1. Erstellen Sie die Anwendung auf dem Emulator und sehen Sie.
  2. . , . id Xcode .




Ich habe S4 und S1 zum Testen verwendet. Da es sehr schwierig ist, viele Dinge an der Uhr selbst zu überprüfen, erwies es sich als unglaublich praktisch, bestimmte Zustände (Zustände) zu isolieren, sie auf eine andere Komponente zu übertragen und dort bereits Tests von allen Seiten abzudecken.

Der zehnte Xcode (der vor Oktober 2019 war) freute sich, dass die Anwendung aus irgendeinem Grund, als sie auf der Uhr gestartet wurde, im Simulator nicht mehr funktionierte. Es wurde durch Abhacken des Handelsdesinfektionsmittels entschieden, wenn jemand interessiert ist.

Dementsprechend müssen Sie beim Zusammenstellen von Zielen mit dedizierten Zuständen und mit gemeinsamer Logik (es gab viele davon) diese mit der Uhr kompatibel machen. Wir haben UIKit versehentlich ein paar Mal angeschlossen, und dies ist das UI-Framework des Telefons, das auf der Uhr nicht unterstützt wird. Wenn Sie versehentlich in der Version abholen, wird die Bibliothek einfach keine Verbindung herstellen.

Autonomie


Grundlegender Anwendungsfall - Der Benutzer hat eine Uhr und ein Telefon. Er hält sie regelmäßig zusammen und die Uhr kann das Internet vom Telefon aus nutzen.



Mit den neuen Uhrenversionen wurde es möglich, Ihr eigenes WLAN und Ihre eigene Uhr-SIM-Karte zu verwenden (es gibt eine eingebaute E-Sim).

Unsere Aufgabe ist es, Favoriten zwischen zwei Anwendungen (am Telefon und auf der Uhr) zu synchronisieren. Jedes Mal, wenn wir anfangen, versuchen wir, die letzte Wahrheit zu lesen, und jedes Mal, wenn wir die Liste ändern, versuchen wir, sofort das zweite Gerät zu finden und ihm davon zu erzählen. Es stellt sich natürlich nicht immer heraus, daher synchronisieren wir, wenn möglich, beim Start. Wenn es zwei verschiedene Favoriten gibt, die mit Konflikten konfrontiert sind, halten wir es für genauer, was am Telefon ist, und lösen Konflikte zu seinen Gunsten.

Andernfalls ist die Anwendung nicht mit dem Telefon verbunden. Der Cache befindet sich im Inneren, Anforderungen an das Netzwerk werden von der Uhr (falls möglich) über die Brücke über das Telefon gesendet (falls möglich). Infolgedessen können Sie es so lange autonom verwenden, wie Sie möchten, aber Sie müssen die Anwendung nur irgendwie zum ersten Mal installieren (unsere Version unterstützt keine Installation von der Uhr direkt von der App aus). Danach können Sie die Synchronisation vergessen, wenn Sie möchten. Vor watchOS 2 bestand das übliche Anwendungsschema darin, dass alles am Telefon gezählt und erledigt wurde und die Uhr nur das Ergebnis lieferte.

Gesamt


Die Basisanwendung für iOS hier . Die Uhrenanwendung ist damit gekoppelt. Die Anwendung verwendet eine Version der Version, passt sich jedoch auf einem bestimmten Gerät an die Geschwindigkeit an und passt die Benutzeroberfläche an die Bildschirmgröße an. Die erste Berechtigung bei der Installation per Telefon am selben Ort, Kopieren von Favoriten und häufigen Routen. Weitere Synchronisation oder autonome Existenz. Geolokalisierung über das Telefon (dies ist erforderlich, um zu verstehen, ob Sie in Moskau oder aus Moskau sind. Wenn Sie Geo nicht zulassen oder nicht, handelt es sich um zeitorientierte, invertierende Morgenanfragen.) Es gab ungefähr so ​​viele Installationen wie erwartet (wir haben berücksichtigt, dass es in Russland nicht viele Stunden gibt und die Benutzer in elektrischen Zügen sitzen). Den Bewertungen nach zu urteilen, freuen sich die App-Benutzer auf der Uhr, ihren Zeitplan auf der Rolltreppe zu sehen.

All Articles