
[ad_1]
Créez un projet SwiftUI bien documenté, organisé et évolutif à l’aide de l’architecture MVVM qui fera dire « wow » à vos réviseurs de code.

SwiftUI est le nouveau framework en plein essor construit par Apple, et il est construit sur leur langage de codage open source Swift. Bien qu’il ait encore du rattrapage à faire avec UIKit en termes de fonctionnalités, SwiftUI fournit aux développeurs une syntaxe déclarative pour créer des vues. En conséquence, il peut avoir un beau code évolutif qui crée une belle interface utilisateur.
Passons à la construction d’un projet optimisé.
L’architecture MVVM (modèle, vue, modèle de vue) présente trois principaux types de structure de données :
- Vues sont des interfaces utilisateur qui affichent les propriétés d’un modèle de vue. L’utilisateur interagit avec la vue, et la vue gère les interactions de l’utilisateur en appelant le modèle de vue.
- Voir les modèles encapsulez la logique de la vue, y compris les appels d’API, la gestion des événements ou des données et le stockage des propriétés importantes.
- Des modèles sont représentatifs des données. Ce sont des objets créés à partir des résultats de l’API, utilisés pour contenir des informations utilisateur ou des objets abstraits dans votre application.
Commençons notre projet optimisé en créant un exemple de vue, de modèle de vue et de système de modèles. En cours de route, je partagerai quelques conseils pour vous aider à le garder évolutif et documenté.
Nous allons commencer par le modèle. Puisque vous écrivez en Swift, vous devrez décider d’utiliser une classe ou une structure.
Des classes sont passe-par-référence ; tandis que Structures sont passés par valeur.
Apple vous recommande d’utiliser des structures pour plusieurs raisons, notamment la sécurité de la mémoire et la réduction de la complexité. Cependant, le le choix vous appartient.
Dans mon exemple, j’ai créé un Food
modèle qui a un nom et si c’est mon préféré. Je vais l’utiliser pour créer une application qui affiche tous mes aliments préférés.
Il se passe beaucoup de choses ici. Mais notons comment les choses ont été mises en place :
- La
Food
struct avait une documentation multiligne avec/** */
. Dans la discussion approfondie de la documentation, un lien versFoodView
est fourni en utilisant la notation double backtick. - Chaque propriété a une documentation sur une seule ligne avec
///
. Chaque méthode a une documentation multi-lignes. - UN
// MARK: —
L’instruction délimite les propriétés et les méthodes. Nous l’utiliserons pour distinguer les propriétés, les méthodes, les initialiseurs, les classes/structures/énumérations imbriquées et d’autres types d’implémentation. - Une propriété calculée
emoji
renvoie un emoji basé sur le nom de l’aliment. Si vous souhaitez afficher du contenu lié uniquement au modèle, il est recommandé d’encapsuler les propriétés ou les fonctions calculées dans la logique de votre modèle. Vous verrez l’avantage de cela quand nous écrivonsFoodView
. - Le modèle a également des méthodes utiles, comme
eat()
.
Et c’est tout! Les modèles sont assez simples. Si vous travaillez avec Codable
vous pouvez également implémenter manuellement CodingKeys
, encode(to:)
et init(from:)
dans votre modèle.
Maintenant, notre modèle de vue prendra un tas de Food
modèles, et cela nous permettra de les afficher et de les modifier :
Choses à noter ici :
FoodViewModel
conforme àObservableObject
nous fournissant@Published
wrappers qui nous permettent de maintenir à jour l’état de notre application.- j’ai utilisé
// MARK: —
pour délimiter les propriétés enveloppées et non enveloppées par préférence personnelle. - Une propriété publiée
allFoods
donne accès à tous mes aliments. Un bon endroit pour charger/enregistrer des données comme celle-ci est dans le modèle de vue. toggleFavorite(food:)
prend dans unBinding<Food>
objet, afin que je puisse mettre à jour le statut préféré de l’aliment via une référence (puisque les structures sont transmises par valeur).
FoodView
affichera les aliments préférés de l’utilisateur. Nous allons commencer par une vue défilante qui répertorie un tas d’éléments, affichant des objets alimentaires.
Comme les objets alimentaires sont indépendants, je vais créer un vue de soutien qui affiche uniquement cet objet. J’utilise des vues complémentaires pour que mon body
la propriété est agréable, propre et lisible.
Regarde:
Et il affiche :

Quelques conseils sur la vue ci-dessus :
- La
// MARK: —
le délimiteur sépare les propriétés enveloppées, la vue du corps et les vues de support. - J’ai extrait l’élément individuel dans une vue de support pour aider à améliorer la lisibilité et la vitesse de
body
. L’extraction de vues vers des variables/méthodes facilite également le débogage, car le compilateur SwiftUI a souvent du mal à compiler de grandes vues imbriquées. - Les touches finales, comme la mise en majuscule des noms des aliments, sont utilisées dans la vue pour améliorer l’apparence. Il est recommandé d’utiliser des propriétés calculées dans des modèles ou des modèles de vue pour améliorer la lisibilité du code.
Et nous avons terminé. Nous avons configuré notre projet MVVM de base avec quelques optimisations. Construisons là-dessus, en ajoutant quelques détails supplémentaires.
Maintenant, nous avons besoin d’un objet pour faire circuler l’information globale. j’utilise un Global
@EnvironmentObject
singleton pour gérer cela.
En règle générale, vous souhaiterez stocker les informations utilisées dans votre application dans Global
. Dans la plupart de mes applications, je stocke les données utilisateur dans un activeUser
propriété. Voici un exemple simple d’un Global
classer:
Dans mes vues, j’utilise le code suivant pour définir l’objet d’environnement et le transmettre à ma vue racine :
let global = Global()
...
MyMainRootView().environmentObject(global)
Ensuite, pour accéder à mon objet Global dans toutes mes vues enfants :
/// The Global `EnvironmentObject`.
@EnvironmentObject var global: Global
Pour plus d’informations sur la mise en œuvre d’un EnvironmentObject
dans vos vues, consultez cet article Hacking with Swift.
Depuis que j’utilise constamment Global
dans mes projets, j’ai créé un extrait de code qui aide à rendre cela plus rapide.
Les extraits de code sont parfaits pour saisir du code pré-écrit avec des espaces réservés facultatifs. Vérifier cet article de Sarunw pour en savoir plus sur la création de vos propres extraits de code dans Xcode.

Jusqu’à présent, nous avons défini un modèle de vue pour aider à gérer diverses logiques liées à FoodView
. Mais de nombreux projets utiliseront plusieurs modèles de vue. Nous aurons donc besoin d’un moyen d’abstraire nos modèles de vue pour obéir à un seul ViewModel
protocole.
Une chose que nous voudrons garder à l’esprit lors de la construction de notre ViewModel
protocole est notre besoin occasionnel d’accéder à notre Global
objet. Idéalement, nous passerions un global
instance dans l’initialiseur du modèle de vue.
Cependant, si vous essayez de le faire, vous rencontrerez des problèmes. Vous ne pouvez pas passer global
dans l’initialiseur du modèle de vue, comme global
est disponible uniquement après les propriétés de la vue, y compris le modèle de vue, ont été initialisées.
Cela signifie que nous devons injecter la global
objets en tant que dépendance pour notre modèle de vue. Et puisque nous travaillons sur un protocole de modèle de vue général, nous pouvons coder cette injection de dépendance afin que chaque modèle de vue que nous créons prenne automatiquement en charge global
injection:
protocol ViewModel: ObservableObject { // MARK: - Properties /// The global instance.
var global: Global? { get set }
}extension ViewModel { // MARK: - Methods /**
Prepares the view model with the global instance. - parameter global: The global instance, taken from a `View`
*/
func prepare(with global: Global) {
self.global = global
}
}
C’est le code (avec documentation supplémentaire) que j’utilise pour définir le ViewModel
protocole dans tous mes projets.
Ce protocole de modèle de vue équipe une nouvelle méthode, prepare(with:)
ce qui vous permet de fournir un Global
instance à votre modèle de vue. Appelez-le à l’intérieur onAppear(perform:)
et vous pourrez accéder à votre global
objet dans votre modèle de vue !
Vous pouvez organiser et structurer votre projet comme vous le souhaitez. Étant donné que notre projet est construit à partir de l’architecture MVVM, nous pouvons organiser son contenu dans les dossiers Model, View Model et View. Le contenu restant peut aller dans d’autres dossiers :
Lifecycle
dossier, pour les fichiers pertinents pour l’ensemble de l’application, tels queAppDelegate
,yourApp
ouGlobal
.Utilities
dossier, pour les méthodes d’assistance, les protocoles supplémentaires, etc.Extensions
pour Swift et les extensions de module.Components
pour les petites vues SwiftUI hautement réutilisables (non dépendantes de ViewModel).View Modifiers
pour les modificateurs de vue personnalisés.Styles
pourButtonStyles
,MenuStyles
,PickerStyles
,TextFieldStyles
etc.Enumerations
pour les énumérations à l’échelle du projet.Assets
si vous souhaitez regrouper des actifs non compatibles avec le catalogue d’actifs de votre projet.
Voici comment j’ai structuré le projet que nous avons construit dans cet article :

Si vous souhaitez revoir ce qui a été construit, ou si vous souhaitez l’utiliser comme modèle, vous pouvez consulter l’intégralité du projet sur GitHub.
Comme exemple supplémentaire à plus grande échelle, voici comment mon projet personnel Flowductive
est structuré :

Ce projet utilise la même architecture MVVM, mais a un code multiplateforme séparé en fonction des besoins Platform
et Shared
répertoires. Si vous êtes curieux d’écrire du code multiplateforme, j’écrirai des articles concernant le développement multiplateforme dans un futur proche.
Merci d’avoir lu.
[ad_2]
Télécharger ici