Expertise · Applications mobiles
Applications pour téléphone, construites de sorte que la logique puisse être vérifiée sans téléphone.
Nous construisons des applications natives iOS en Swift, avec des capteurs et HealthKit, et des applications à un seul code pour iOS, Android et le web lorsque le projet ne demande pas de capteurs. Le noyau logique est testé séparément de l’écran.
Déjà construitSunt trei implementări proprii, nu una. Un depozit cu cinci ținte de aplicație (patru iOS și una macOS) definite în `project.yml`, ale cărui teste de logică le-am rulat azi: 160 din 160 trec. O a doua aplicație iOS, în alt proiect, cu 40 de fișiere Swift și HealthKit. Și o a treia direcție, cu un singur cod pentru iOS, Android și web, a cărei variantă web răspunde astăzi. Rezerva care schimbă răspunsul la întrebarea pe care o pune orice cumpărător înainte de toate: niciuna dintre aplicațiile noastre nu este publicată în App Store sau Google Play. Motivul e unul singur și are nume — `DEVELOPMENT_TEAM` este gol în configurația de proiect, adică lipsește identificatorul de echipă din Apple Developer Program. Mașina are o identitate de semnare validă, suficientă pentru instalare pe dispozitiv propriu, insuficientă pentru distribuție în magazin. E o problemă de cont, nu de cod, dar rămâne o problemă și o scriem aici, nu la subsol.
Une application mobile a deux parties qui se cassent différemment. La partie qui lit les capteurs et calcule quelque chose — un angle, un score, un état — et la partie qui dessine des écrans. Nous les gardons séparées, et pas pour des raisons esthétiques : dans notre principal dépôt iOS, les fichiers du noyau n’importent pas l’interface, si bien qu’ils peuvent être compilés directement avec `swiftc` sur Mac et exécutés comme un programme ordinaire, sans simulateur et sans téléphone. La suite compte 160 vérifications regroupées en 16 étapes ; nous l’avons exécutée aujourd’hui et elle passe intégralement. C’est la raison pour laquelle nous pouvons dire ce que fait exactement un algorithme, au lieu de dire qu’il « fonctionne bien ».
Sur iOS, nous travaillons en Swift 6, avec une cible minimale iOS 17. Le même dépôt définit cinq applications comme cibles séparées : quatre pour iPhone et une pour macOS, et la version macOS réutilise quinze fichiers du noyau de l’iOS, sans copie. Les capteurs sont lus à la source : l’interface Apple pour les capteurs des écouteurs expose l’orientation de la tête, et l’application compare l’angle courant à une position que l’utilisateur calibre au début de la session. Les seuils ne sont pas des « réglages internes » : en dessous de 7° c’est droit, entre 7° et 13° c’est une inclinaison, au-dessus de 13° maintenu trois secondes déclenche l’alerte, et le lissage utilise une moyenne exponentielle avec le coefficient 0,15. Les quatre valeurs se trouvent dans quatre lignes de code consécutives et peuvent être montrées.
Quand le projet n’a pas besoin de capteurs, nous ne recommandons pas le natif. La troisième direction du portefeuille est un seul code qui se compile pour iPhone, Android et navigateur — React Native avec Expo — et la version web est publiée et répond aujourd’hui. La différence pratique pour le client : un questionnaire, un calculateur ou un tableau de bord ne justifie pas deux équipes et deux dépôts ; une application qui écoute un capteur à vingt mesures par seconde, oui.
Ce que nous ne pouvons pas encore. Aucune de nos applications n’est dans l’App Store ou Google Play. Pas parce qu’elles ne compilent pas — elles compilent, s’installent sur le simulateur et passent les tests — mais parce que, dans la configuration du projet, l’identifiant d’équipe Apple est vide, c’est-à-dire qu’il n’existe pas d’inscription au Apple Developer Program liée à ces builds. Sur Mac, il existe une identité de signature valide, de type développement, qui suffit pour l’installation sur son propre appareil et ne suffit pas pour la boutique. Pour un projet client, le compte développeur est ouvert au nom de la société cliente et lui appartient — c’est la discussion qui doit avoir lieu au début, pas à la fin.