Ce que vous voudrez savoir avant de rédiger une application pour Apple Watch: notre expérience

Une plateforme très lente vous attend, la transition vers de nouveaux frameworks, des tests avec une ambiance particulière et des notifications de l'OS «hey, move» une seconde avant le déchargement forcé du thread.


Oui, c'est ma main velue.

Notre horaire de train compte 600 000 personnes par jour. Et chaque année de plus en plus - grâce à l'application mobile. Nous avons pensé et décidé de faire une version pour la montre. Le problème était que nous ne savions pas combien d'Apple Watch existe sur le marché russe et combien d'entre eux voyagent dans des trains électriques. Mais dans tous les cas, il était nécessaire de comprendre comment procéder, alors nous avons pris et écrit à Apple pour demander des statistiques.

Curieusement, ils ne l'ont pas fait. Ensuite, ils ont aidé de toutes les manières possibles, mais ici, avec les statistiques, il y a un problème direct. Personne n'avait de données normales depuis un an, et même étudier les rapports de vente n'a pas aidé. Les montres sont portées à bien des égards dans le «gris» et non pas de notre région au départ.

Pourquoi des statistiques? Pour comprendre combien de générations il y a sur le marché. Au final, nous avons décidé de prendre en charge tous les appareils.


Les dernières statistiques que nous connaissons pour 2017 ressemblaient à ceci:

  • 1re génération (tout) - 57%
  • Série 2 (tous) - 32%
  • Série 1 (tous) - 11%

Pour l'avenir, nous avions trois mois après la sortie en 2019 comme ceci:

  • Apple Watch Series 3 (tous) - 36%
  • Série 4 (tous) - 31%
  • Série 5 (toutes) - 24%
  • 1re génération (tous) - 4,5%
  • Série 2 (tous) - 2,5%
  • Série 1 (tous) - 2%

Répartition des tailles d'écran des deux dernières révisions:

  • S4 grand à 44 mm - 58%, petit 40 - 42%.
  • S5 grand - 60%, petit 40%.

Les modèles précédents ont encore 38 mm, dans le nombre total de toutes les installations, il est légèrement inférieur à 20%, principalement en raison de S3. Soit dit en passant, nous avions besoin de polices pour différentes tailles d'écran - nos concepteurs ont créé des polices adaptatives.

Plateforme très lente


Ainsi, nous semblons ne pas avoir beaucoup d'appareils, mais dont environ 5% (comme prévu) seront très anciens. Les premières heures ont généralement été conçues, semble-t-il, comme un appareil qui affiche des images générées sur le téléphone. Puis il est apparu son propre système d'exploitation développé, et dans les révisions ultérieures - également un Wi-Fi et une carte SIM.

La carte SIM en Russie ne fonctionne pas. Peut-être, cette année, les opérateurs seront d'accord, mais pour l'instant, il n'y a que le wifi et la communication par téléphone (la montre se connecte à l'iPhone via Bluetooth, puis utilise sa connexion Internet).

La logique de travail avec le réseau, la mémoire et le disque est presque la même que dans iOS.Je veux dire, la logique elle-même est commune, les services sont communs, mais il y a toujours une embuscade avec les bibliothèques - en fait, peu de gens développent pendant des heures, donc il n'y a peut-être pas de cadres et d'outils populaires sur iOS / iPadOS. Dans notre cas, cela signifiait la nécessité d'abandonner le tas de bibliothèques que nous avons accrochées à une application iOS avec le mouvement de main habituel.

Sans exception, toutes les montres effectuent des accès au disque très lents par rapport à la façon dont elles peuvent être lues depuis la mémoire. Si sur un iPhone, vous ne pouvez pas vraiment vous soucier de l'emplacement exact de la table de 40 Ko, alors sur la montre, il est essentiel de le garder en mémoire ou de le recevoir par voie aérienne. La chose la plus importante est de ne rien lire du disque.

Bien sûr, plus l'horloge est récente, plus tout tourne vite, mais nous travaillons en fait pour S3 avec la prise en charge des appareils antérieurs et des fonctionnalités supplémentaires pour S4 et S5.

La version alpha de l'application, qui montrait le chemin du retour, se chargeait pendant des heures des dizaines de secondes. L'horaire du MCC a été affiché pendant 20 secondes sur les 4 trains les plus proches. Le problème était dans le rendu de la table - trop d'éléments individuels. Imaginez un navigateur moderne qui essaie de rendre quelque chose sur le noyau 386SX. Nous avons donc eu des problèmes similaires.

Naturellement, c'est pourquoi elle est alpha à fouiner avec elle. En version bêta, nous répartissons la charge sur les threads (interceptant une fonctionnalité en cours de route lorsque l'horloge démarre sur watchOS 4, le point d'entrée principal ne démarre pas sur le courant dominant). Pendant les heures "faibles", le nombre de cellules dans l'interface était limité.


Chacun d'eux a été rendu pendant environ une seconde.



Quelques optimisations de l'interface utilisateur elle-même, et a volé vers S4, et pour les appareils plus anciens ont dû réduire le nombre de trains affichés.

Ils ont inséré au-dessus et au-dessous de «montrer les défunts» et «montrer ensuite», et aux élus - «montrer tout». Étant donné que cet horaire change souvent, il était souvent nécessaire de le redessiner: nous parlons de situations où la composition de la table change soit à cause d'un train parti, soit à cause d'un changement d'horaire (nous montrons le mouvement en temps réel, c'est-à-dire que nous savons où exactement chaque particulier train en fait, et comment cela affectera toutes les autres gares le long de l'itinéraire).

Il arrive souvent que les données deviennent obsolètes une seconde après la demande. Avec l'approche de base, toute la table était tordue, c'est la manière standard pour iOS. Là, la mise à jour est généralement imperceptible. Et ici, ils ont fait beaucoup de conneries basées sur le traitement du tableau entrant, qui analyse d'abord les données, puis construit le diff, puis trouve les éléments d'interface utilisateur qui peuvent être modifiés sans toucher les autres, puis ne les met à jour que. Il n'y a pas de bibliothèques appropriées pour une solution complète sur WatchOS, mais il existe un kit de différenciation, qui, selon le tableau de données avec balisage, donne une liste de comment et de ce qui a changé par index. Ils ont écrit leur code autour de lui et l'ont placé sur toutes les tables. Cela a donné une augmentation des mises à jour de performances.

En général, les N trains les plus proches sont rapidement affichés, et si vous aimez attendre, mais que vous voulez une image complète, vous pouvez cliquer sur "tout afficher".

Comme je l'ai dit, le cadran de la montre est grand, mais lent. Tout d'abord, nous avons utilisé un ensemble standard de bibliothèques iOS fonctionnant sur le disque. Nous avons obtenu le programme, l'avons enregistré sur un disque, le service demandé, l'avons extrait du disque, l'avons déroulé à l'écran. Il s'est avéré que vous devez stocker le cache en mémoire. Et pourtant, nous avons l'habitude d'enregistrer tous les états de travail de l'utilisateur sur le disque, puis de les lire à partir de là - nous n'avons eu qu'à enregistrer et stocker tout ce que nous pouvions en mémoire.



Pourquoi un enregistrement constant est-il nécessaire? Parce que si l'utilisateur change d'application, le déchargement se produit presque instantanément. Vous n'avez généralement pas le temps d'écrire quoi que ce soit sur le disque de freinage, vous devez donc le faire constamment et de manière itérative pendant que l'utilisateur travaille.

Et puis nous approchons de la prochaine embuscade.

Conservation de l'énergie maniaque


La pile de la montre est petite et l'ensemble du système d'exploitation est affûté afin de préserver au maximum l'énergie. En pratique, cela peut signifier que l'utilisateur effectue les opérations suivantes:

  1. Commence à télécharger quelque chose (par exemple, un horaire complet)
  2. Abaisse la main
  3. Attend
  4. Lève la main pour voir ce qui est chargé

En fait, les événements suivants se produisent:

  1. L'utilisateur commence à télécharger le programme complet
  2. Abaisse la main
  3. Les montres comprennent qu'elles ne fonctionnent pas avec elles et placent le processus dans un analogue d'hybernate.
  4. L'utilisateur attend, puis lève la main pour regarder le résultat.
  5. Au moment de l'ascension, la montre comprend qu'elle continue de travailler avec eux, de se réveiller et de réveiller le processus.
  6. L'utilisateur voit le début de l'indicateur de téléchargement.

Dans le même temps, du point de vue du thread, cela peut être le bon moment ou une «très longue seconde» - si vous écrivez du code à des délais d'attente, vous pouvez soudainement attraper même une année où une demi-seconde a attendu. N'oubliez donc pas que le temps est relatif.

Le processus d'éveil vous menace avec un long processus de débogage - vous pouvez y attraper des plantages sur le fait que l'endroit est libéré, ou que quelque chose d'intéressant se produit.

Le processus d'endormissement peut se transformer en un processus de déchargement (sans se réveiller), vous devez donc écrire certaines choses sur le disque. Le système d'exploitation indique le fil «Aller en arrière-plan» et appelle la méthode appropriée. Habituellement, vous avez environ une seconde pour sortir rapidement et vider en arrière-plan. Lorsqu'un utilisateur fait cela en écrivant sur un disque (ce qui, je le rappelle, est incroyablement lent sur les appareils jusqu'à S4), l'enregistrement peut ne pas avoir lieu. Pour ce faire, vous devez passer en mode «opération importante» et, à l'aide de plusieurs appels spéciaux, garder le fil «conscient». Pour ce faire, vous avez besoin d'un gestionnaire distinct qui demande au processus d'enregistrement de se terminer, puis libère le thread en veille.

Architecture


Notre première application en 2017 n'était qu'un blanc, capable de montrer le calendrier généré sur le téléphone. Il a été utilisé pour afficher les données d'un train longue distance sur une voie, une voiture et un lieu.

La version moderne pour les trains est «adulte» et autonome, c'est-à-dire qu'elle peut vivre à tout moment sans téléphone. Même à partir du moment de l'installation (bien que la façon habituelle pour l'application d'accéder à la montre soit par le téléphone, et à ce stade, il est très pratique de copier les données de profil et tous les itinéraires sélectionnés à partir du téléphone).

L'architecture de la montre est probablement la plus moderne des modèles iOS. Redux n'est pas un problème. Comme dans la "grande" application, nous utilisons la machine d'état. Le MVC standard est le suivant: il y a un modèle d'une part, il y a des vues pour ce modèle, au milieu du contrôleur. Le contrôleur prend les données du modèle, convertit, affiche à l'écran. Dans le sens opposé, le contrôleur écoute les messages de visualisation et fournit des données au modèle. Sur la base de ce modèle, de nombreux types d'architectures ont été créés.

Nous avons un état où les événements peuvent s'envoler et muter. Les effets secondaires, qui font un travail utile, peuvent s'écarter de l'état. À partir de ces résultats, les événements s'envolent vers l'État. L'état complet de l'application est stocké dans l'histoire, un seul point de vérité. L'état peut être divisé en morceaux et divisé, mais dans tous les cas, il stocke l'ensemble de données complet. L'implémentation spécifique de l'architecture dépend de la religion, nous avons RXFeedback.

La machine d'état est très bien couverte par les tests. Cela nous a fait gagner beaucoup de temps uniquement sur la montre, car les tests ne peuvent pas être effectués à l'intérieur de la montre elle-même. Ce n'est pas un iPhone pour vous. Ici, vous devez faire ceci:

  1. Générez l'application sur l'émulateur et voyez.
  2. . , . id Xcode .




J'ai utilisé S4 et S1 pour les tests. Comme beaucoup de choses sont très difficiles à vérifier sur la montre elle-même, il s'est avéré extrêmement pratique d'isoler des états spécifiques (états), de les transférer vers un autre composant et de les couvrir de tests de tous les côtés.

Le dixième Xcode (qui était avant octobre 2019) s'est réjoui que, pour une raison quelconque, lorsque l'application a démarré sur l'horloge, elle ait cessé de fonctionner dans le simulateur. Cela a été décidé en coupant le désinfectant commercial, si quelqu'un est intéressé.

Par conséquent, lors de l'assemblage de cibles avec des états dédiés et avec une logique commune (il y en avait beaucoup), vous devez les rendre compatibles avec l'horloge. Nous avons accidentellement accroché UIKit plusieurs fois, et c'est le cadre d'interface utilisateur du téléphone, il n'est pas pris en charge sur l'horloge. Si vous récupérez accidentellement dans la version - la bibliothèque ne se connectera tout simplement pas.

Autonomie


Cas d'utilisation de base - l'utilisateur a une montre et un téléphone. Il les tient régulièrement ensemble et la montre peut utiliser Internet à partir du téléphone.



Avec les nouvelles versions de montres, il est devenu possible d'utiliser votre propre Wi-Fi et votre propre carte SIM d'horloge (il y a une e-sim intégrée).

Notre tâche consiste à synchroniser les favoris entre deux applications (sur le téléphone et la montre). Chaque fois que nous commençons, nous essayons de lire la dernière vérité, et chaque fois que nous changeons la liste, nous essayons de trouver immédiatement le deuxième appareil et de lui en parler. Il s'avère, évidemment, pas toujours, donc, si possible, nous synchronisons au démarrage. S'il y a deux favoris différents qui sont confrontés à des conflits, nous considérons plus précis ce qui est au téléphone et nous résolvons les conflits en sa faveur.

Sinon, l'application n'est pas connectée au téléphone. Le cache est à l'intérieur, les demandes au réseau sont envoyées depuis l'horloge (si possible), sinon, via le pont via le téléphone. En conséquence, vous pouvez l'utiliser de manière autonome aussi longtemps que vous le souhaitez, mais il vous suffit d'installer la première fois de manière ou d'autre l'application (notre version ne prend pas en charge l'installation depuis l'horloge directement depuis l'application). Après cela, vous pouvez oublier la synchronisation, si vous le souhaitez. Avant watchOS 2, le schéma d'application habituel était que tout était compté et effectué sur le téléphone, et l'horloge ne rendait que le résultat.

Total


L'application de base pour iOS ici . L'application de surveillance y est associée. L'application utilise une version de la version, mais sur un appareil spécifique, elle s'y adapte en termes de vitesse et adapte l'interface à la taille de l'écran. La première autorisation lors de l'installation par téléphone, au même endroit, la copie des favoris et des itinéraires fréquents. Synchronisation plus poussée ou existence autonome. Géolocalisation depuis le téléphone (cela est nécessaire pour comprendre si vous êtes à Moscou ou depuis Moscou, si vous n'autorisez pas la géo ou non, elle est temporelle, inversant les demandes du matin). Il y a eu autant d'installations que prévu (nous avons tenu compte du fait qu'il n'y a pas beaucoup d'heures en Russie et que leurs utilisateurs sont dans des trains électriques). À en juger par les avis, les utilisateurs de l'application sur la montre sont heureux de voir leur horaire sur l'escalator.

All Articles