Meilleures pratiques et outils pour développer des applications iOS

Lors du développement d'applications mobiles, j'ai dû créer des projets à partir de zéro plus d'une fois. Dans le même temps, mon équipe et moi avons toujours passé beaucoup de temps sur la configuration de base du projet, comme l'intégration d'outils tiers, la configuration de la structure du projet, l'écriture de classes de base, l'intégration de bibliothèques externes, etc.

J'ai décidé que le temps de lancement du projet pouvait être réduit et que la majeure partie du processus pouvait être automatisée. Dans le même temps, j'ai rassemblé les meilleures pratiques et outils que nous avons utilisés, et préparé un modèle de projet que nous utilisons lors du démarrage de nouveaux projets. Un tel modèle devrait permettre au développeur de gagner du temps pour configurer un nouveau projet, ainsi que de fournir une structure de projet commune à laquelle chaque membre de l'équipe s'habituera, afin que vous n'ayez plus à penser et à étudier la structure d'un nouveau projet pour lui. Maintenant c'est toujours pareil.

Chaque outil ou approche ajouté au modèle mérite un article distinct, mais je voudrais essayer de résumer chaque paragraphe et expliquer brièvement pourquoi je les ai inclus dans cet article.

Cocoapods


Je ne pense pas que Cocoapods nécessite une soumission. Il s'agit d'une bibliothèque de gestion des dépendances externes pour les projets iOS. Il existe depuis longtemps et est fiable et éprouvé sur le terrain dans des milliers (voire des millions) de projets. Il existe également des gestionnaires de dépendance alternatifs, par exemple: Carthage , mais j'ai décidé de continuer avec Cocoapods, car il a la plus large gamme de projets open source pris en charge. L'utilisation de Cocoapods est très simple et est livrée avec un index de recherche qui facilite la recherche de packages pouvant être utiles à tout moment.

Un projet de modèle est fourni avec un Podfile simple qui contient Swiftlint et R.swift. Le modèle comprend également un gemfile pour gérer la version des Cocoapods utilisée pour la gestion des dépendances. Cette solution est souvent ignorée par les développeurs, mais elle évite les problèmes qui surviennent lorsque les développeurs de votre équipe installent des dépendances à l'aide de différentes versions de Cocoapods. Gemfile utilise de force la même version de Cocoapods pour toute l'équipe.

Swiftlint


Swiftlint est un outil très utile pour appliquer certaines règles et style d'écriture pour chaque développeur de la même équipe. Ce système pourrait être considéré comme un système de vérification de code automatisé qui avertit le développeur des moments dangereux, tels que, par exemple, les lancements de force, les essais de force, etc., mais en plus de ce qui précède, ce système applique un style général d'écriture de code, de surveillance de sorte que tous les développeurs suivent les mêmes règles associées au "style de code", par exemple: les retraits ou les intervalles. Cette approche présente d'énormes avantages, non seulement pour gagner du temps sur la vérification du code, mais aussi pour rendre les fichiers de projet reconnaissables, ce qui augmente leur lisibilité et, par conséquent, leur compréhension par tous les membres de l'équipe de développement. Ce lien fournit une liste de toutes les règles. Dans le modèle Swiftlint, il est installé à l'aide de Cocoapods et est inclus dans l'étape "Phases de compilation", il affichera donc un avertissement au développeur chaque fois que le projet est compilé.

R.swift


R.swift est un outil permettant d'obtenir des ressources fortement typées et remplies automatiquement, telles que des images, des segments de police et des localisations. Il effectue toutes les actions ci-dessus en analysant le projet et en créant les classes nécessaires pour obtenir des ressources. Le plus grand avantage de cette bibliothèque est que lorsqu'elle utilise des ressources, elle crée du code de programme:

  • Entièrement typé - moins de transtypages et d'hypothèses sur la méthode qui sera retournée
  • Temps de compilation vérifié - plus de lignes non valides qui empêchent l'application de s'exécuter pendant l'exécution du code
  • Autocompleted - pas besoin de deviner à nouveau l' image nom / nib / storyboard

Considérez le code suivant à l'aide de l'API de chaîne officielle:

let icon = UIImage(named: “custom-icon”) 

Si vous avez fait une erreur dans le nom de l'image, vous obtiendrez zéro. Si un membre de votre équipe change le nom de la ressource d'image, ce code renverra zéro ou son exécution sera arrêtée si vous forcez l'image à se développer. Lorsque vous utilisez R.swift, cela ressemble à ceci:

 let icon = R.image.customIcon() 

Vous pouvez maintenant être sûr que l'icône existe vraiment (le compilateur vous avertira si ce n'est pas le cas, grâce aux vérifications de temps de compilation), et vous serez sûr de ne pas faire de faute de frappe au nom de l'icône, car vous utiliserez la saisie semi-automatique.

R.swift est installé à l'aide de Cocoapods et s'intègre au modèle dans la phase de compilation et générera des classes de shell Swift pour chaque compilation. Cela signifie que si vous ajoutez un fichier / image / localisation / police / couleur / stylo, etc., tout cela sera disponible via R.swift après la compilation du projet.

Fichier AppDelegate séparé pour les tests


Très souvent, ils oublient la bonne pratique d'utiliser une classe TestAppDelegate distincte lors de l'exécution des tests. Pourquoi est-ce une bonne idée? En règle générale, la classe AppDelegate fait beaucoup de travail au démarrage de l'application. Il peut avoir une logique de configuration de fenêtre, configurer l'affichage de base de l'interface utilisateur de l'application, exécuter une logique d'enregistrement pour recevoir des notifications, avoir un code de configuration de connexion à la base de données et même parfois passer des appels à l'API du serveur. Les tests unitaires ne devraient pas avoir d'effets secondaires. Vous ne voulez vraiment pas faire d'appels API aléatoires et personnaliser l'intégralité de la structure de l'interface utilisateur de votre application juste pour exécuter des tests unitaires?

TestAppDelegate est également un choix approprié pour obtenir le code que vous souhaitez exécuter une seule fois pendant l'exécution de la suite de tests. Il peut contenir du code qui génère des objets fictifs, des talons de demande de réseau, etc.

Le modèle contient le fichier main.swift, qui est le principal point d'entrée de l'application. Il existe des méthodes dans ce fichier qui testent l'environnement de l'application, et s'il s'agit d'un environnement de test, elles appellent TestAppDelegate.

Indicateurs de profilage des performances du compilateur


Swift est un langage génial, plus facile à utiliser et plus sécurisé que Objective-C (IMO). Mais quand il a été introduit pour la première fois, il avait un gros défaut - le temps de compilation. À l'époque où je travaillais sur un projet dans Swift, qui avait environ 40 000 lignes de code Swift (un projet de taille moyenne). Le code était très lourd, avec des paramètres et une inférence de type, et la compilation d'un assemblage propre a pris près de 5 minutes. Si vous apportez des modifications, même minimes, le projet est recompilé et il faut environ 2 minutes pour voir les modifications. Ce fut l'une des pires expériences que j'ai jamais vécues, et à cause de cela, j'ai presque arrêté d'utiliser Swift.

Ensuite, la seule solution était d'essayer de profiler le temps de compilation du projet et de changer votre code pour que le compilateur fonctionne plus rapidement. Pour aider à résoudre de tels problèmes, Apple introduit des indicateurs de compilation non officiels qui avertissent le développeur qu'il faut trop de temps pour compiler le corps de la méthode ou déterminer le type d'expression. J'ai ajouté ces drapeaux au projet de modèle pour vous avertir du long temps de compilation de votre application.

De nos jours, le temps de compilation a considérablement diminué, et les développeurs doivent très rarement optimiser leur code juste pour réduire le temps de compilation. Mais il vaut toujours mieux tout savoir à l'avance que d'essayer de résoudre ce problème lorsque le projet devient trop important.

Configurations Dev / Staging / Production


Une autre bonne approche (ou, pourrait-on dire, une nécessité) consiste à avoir une configuration et des variables d'environnement distinctes pour les environnements de développement, les tests finaux et la publication d'applications. Actuellement, presque toutes les applications devraient fonctionner avec un serveur, et généralement ces serveurs sont déployés dans plusieurs environnements. L'environnement de développement est utilisé pour un déploiement quotidien par les développeurs pour tester leur code. L'environnement de test final est utilisé pour créer des versions stables ou pour les tests par les testeurs et les clients.

Une façon de prendre en charge plusieurs environnements dans un projet iOS consiste à ajouter des configurations au niveau du projet.

image
Configurations au niveau du projet

Après avoir défini les configurations, vous pouvez créer un fichier Configuration.plist contenant des variables pour chaque environnement.

image
Configuration.plist

Lors du démarrage d'un projet, il est possible d'indiquer quelle configuration doit être utilisée. Vous pouvez le faire dans un diagramme d'assemblage.

image

Vous devez ensuite ajouter une autre propriété au fichier de projet Info.plist. La valeur de cette propriété sera dynamiquement substituée lors de l'exécution au nom de la configuration actuelle.

image
Tout cela est préconfiguré dans le modèle.

Il ne reste plus qu'à écrire une classe capable d'extraire ces variables au moment de l'exécution, selon la configuration sélectionnée dans le schéma d'assemblage. Le modèle contient la classe ConfigurationManager , qui peut récupérer des variables pour l'environnement actuel. Vous pouvez également vérifier l'implémentation de cette classe sur Github pour voir comment cela fonctionne.

Lisezmoi


Chaque projet doit contenir un fichier Lisez-moi, qui contient au moins des instructions pour l'installation des dépendances et le démarrage du projet. Il doit également contenir des descriptions de l'architecture et des modules du projet. Malheureusement, les développeurs n'aiment pas écrire de documentation (le fichier Lisezmoi fait partie de ce travail), et j'ai vu un projet qui a été développé pendant des mois, et il avait même un fichier Lisezmoi. Pour supprimer la charge de l'écriture d'un fichier readme, le modèle contient un fichier readme standard qui couvre l'installation et la structure du projet. Lors de la configuration d'un nouveau projet à l'aide de modèles, vous incluez automatiquement le fichier Lisez-moi.

Gitignore


Actuellement, la plupart des projets utilisent GIT comme système de contrôle de version. Lors de l'utilisation de GIT, les développeurs ne veulent pas ignorer certains fichiers ou dossiers du projet, tels que le dossier de génération ou le dossier de données dérivé. Pour éviter au développeur d'avoir à trouver un fichier gitignore adapté à son projet iOS, le modèle contient le gitignore standard fourni par les membres de Github.

Classes de base pour gérer les liens externes et les notifications


De nos jours, presque toutes les applications doivent gérer les liens externes et les notifications. Pour ce faire, le développeur doit écrire du code standard dans la classe AppDelegate. Ce modèle contient une description de la façon de procéder, il contient également des classes de base qui facilitent l'utilisation des liens externes et des notifications.

Conclusion


Pour résumer, le modèle décrit contient les meilleures approches et intègre des outils tiers utiles. Tout cela devrait permettre à votre équipe de gagner du temps consacré à la mise en place d'un nouveau projet et de fournir une base commune et solide pour le reste du projet. Laissez ce modèle vous servir, vous et votre équipe, pour le bénéfice!

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


All Articles