• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 07/08/2024

Mettez à jour le fichier ViewModel

Avec vos tests unitaires en place, vous êtes maintenant prêt à améliorer et à étendre les fonctionnalités de votre ViewModel. En effet, notre ViewModel, enfin son interface publique (ou API) fait à présent office de contrat définissant clairement quels inputs et outputs peuvent être utilisés par d’autres parties de l’application. Mais il ne fonctionne pas encore. D’ailleurs, nos tests unitaires le confirment. C’est pour cela que nous devons migrer la logique métier.

Récupérez le code à refactoriser

Voici une vidéo qui montre les principales étapes pour identifier le code à refactoriser.

Comme vous le savez maintenant, pour transformer efficacement notre application en suivant l'architecture MVVM, il est crucial de séparer les préoccupations ou responsabilités en identifiant les parties de la logique métier qui doivent être transférées du fichier View (“HomeScreenView”) vers le ViewModel (“HomeScreenViewModel”).

Souvenez-vous, dans la section “Identifiez les correspondances dans la View”, nous avons listé les éléments qui doivent être migrés de la View vers le ViewModel

Pour rappel, ces éléments sont :

  • Inputs :

    • Recherche de projets : Texte saisi dans la barre de recherche.

    • Affichage du formulaire d'ajout de projet : Clic sur le bouton Plus.

    • Ajout d’un projet

    • Suppression de projet : Clic sur l'icôneTrash.

  • Outputs :

    • Texte statique : "Accueil" et "EPCollaboratif".

    • Liste des projets filtrés : Mise à jour de la View en fonction de la recherche et de l'ajout ou suppression de projets.

  • Éléments dynamiques : La propriétéprojectStore doit être déplacée dans le ViewModel et être améliorée par la suite pour représenter les projets à injecter lors de l’initialisation de l’écran “Home”.

Intégrez et ajustez le code dans le ViewModel

Pour transférer efficacement le code depuis la View vers le ViewModel, il est essentiel de suivre une méthode structurée. En effet, la migration de la logique métier ne se résume pas à un simple copier/coller des éléments identifiés précédemment. Il faudra bien souvent ajuster la logique afin de rendre notre ViewModel fonctionnel, sans changer ce que la View envoie ni ce que le ViewModel renvoie. Procédons alors par étape, une fonctionnalité à la fois et en exécutant les tests unitaires associés après chaque migration. Cela permet, petit à petit, de vérifier le bon fonctionnement du ViewModel.

Voici une vidéo qui montre les principales étapes pour intégrer et ajuster le code dans le ViewModel.

Commençons par migrer le contenu la propriétéfilteredProjectqui contient la logique de filtrage des projets à afficher en fonction du contenu de la propriétésearchText. Nous allons ensuite remplacer l’utilisation duprojectStore par la propriétéprojects que nous avions déclarée comme output.

import SwiftUI

class HomeScreenViewModel: ObservableObject {

    // MARK: - Outputs

    @Published var searchText: String = ""
    @Published var showAddProjectView: Bool = false
    @Published var projects: [Project] = []

    var filteredProjects: [Project] {
        if searchText.isEmpty {
            return projects.projects
        } else {
            return projects.projects.filter { $0.name.localizedCaseInsensitiveContains(searchText) }
        }
    }


    let titleText = "EPCollaboratif"
    let homeText = "Accueil"

    // MARK: - Init

    init() {

    }

    // MARK: - Inputs

    func add(_ project: Project) {

    }

    func deleteProject(at index: Int) {

    }
}

Mais du coup pourquoi garder la propriétéprojectscomme output si on expose aussifilteredProject ? 

Bonne question ! Il n’y a plus besoin de rendre la propriétéprojects publique carfilteredProject fournit déjà les informations nécessaires. Cependant, nous avons encore besoin de pouvoir injecter une liste de projets dans notre ViewModel. Nous allons donc rendre cette propriété privée et l’initialiser dans le constructeur du ViewModel via la fonctioninit().

Voici comment implémenter cela dans votre code.

import SwiftUI

class HomeScreenViewModel: ObservableObject {
    // MARK: - Private
    @Published private var projects: [Project] = []

    // MARK: - Outputs

    @Published var searchText: String = ""
    @Published var showAddProjectView: Bool = false

    var filteredProjects: [Project] {
        if searchText.isEmpty {
            return projects.projects
        } else {
            return projects.projects.filter { $0.name.localizedCaseInsensitiveContains(searchText) }
        }
    }


    let titleText = "EPCollaboratif"
    let homeText = "Accueil"

    // MARK: - Init

    init(projects: [Project]) {
        self.projects = projects
    }

    // MARK: - Inputs

    func add(_ project: Project) {

    }

    func deleteProject(at index: Int) {

    }
}

Il ne nous reste plus qu'à migrer le contenu de la propriété qui contient la logique d’ajout et de suppression d’un projet dans la liste de projets. Les deux fonctions add etdeleteProject sont simples à migrer.

Pour ajouter un projet, on l’insère dans la liste de projets du ViewModel. Mais attention, il faut bien vérifier avant que le projet n’existe pas déjà dans la liste. Voici le code associé.

func add(_ project: Project) {
    guard !projects.contains(project) else { return }
    projects.append(project)
}

Pour la fonction de suppression d’un projet, c’est tout aussi simple. Avant de passer à l’action, assurez-vous que l’index du projet souhaité peut être trouvé dans la liste de projets. En effet, tenter d’accéder à un index qui n’existe pas dans une liste fait automatiquement crasher l’application ! Voici le code associé.

func deleteProject(at index: Int) {
    guard projects.indices.contains(index) else { return }
    projects.removeAll { $0.id == filteredProjects[index].id }
}

Pour voir le résultat final de cette migration, jetez un œil au fichier "HomeScreenViewModel".

Testez et validez le ViewModel

Après avoir intégré et ajusté le code dans le ViewModel, il est essentiel de valider cette intégration en utilisant des tests unitaires. Cela garantit que chaque modification fonctionne comme prévu et que l'application reste stable.

Pour cela, allez dans le menu Produit puis Test ou utilisez le raccourci Cmd+U pour exécuter tous les tests. Assurez-vous que tous les tests sont au vert. Vous devriez avoir une liste similaire à celle-ci. 

Interface de tests du projet 'EPCollaboratif'. La couverture du code est de 43 %. La section 'Tests' affiche les résultats des tests sous 'EPCollaboratifTests' et 'HomeScreenViewModelTests', comme 'testAddingDuplicateProject_DoesNotIncreaseProjectCount()
Rapport d'exécution des tests en succès

Ici, vous pouvez constater la bonne exécution des tests, avec des résultats tous au vert. N’hésitez pas aussi à consulter les temps d'exécution et à vérifier si ceux-ci ne sont pas trop longs.

À vous de jouer

Contexte

Vous avez appris comment identifier et transférer la logique métier depuis la View vers le ViewModel. Il est maintenant temps de mettre cela en pratique en refactorisant le fichier "AddTaskView".

Consignes

  1. Reprenez le code à refactoriser que vous avez identifié dans le chapitre “Analysez vos écrans”.

  2. Transférez le code dans le ViewModel.

  3. Testez et validez le ViewModel.

Livrable

  • Un fichier “AddTaskViewModel” mis à jour avec la logique métier transférée depuis la View.

  • Des tests unitaires validant les modifications apportées au ViewModel.

En résumé

  • La migration de la logique métier de la View vers le ViewModel est essentielle pour suivre l'architecture MVVM et séparer les responsabilités.

  • Il faut toujours ajuster le code du ViewModel et de la View pour qu'il fonctionne dans ce nouveau contexte.

  • Le ViewModel définit clairement les inputs et les outputs utilisables (publiques) ou non (privés) par d'autres parties de l'application.

  • Les propriétés privées dans le ViewModel sont initialisées et gérées pour optimiser l'accès et la manipulation des données, sans exposer directement les détails au reste de l'application.

  • Les tests unitaires doivent être mis à jour selon les modifications du ViewModel et doivent être exécutés régulièrement pour vérifier que chaque changement maintient l'intégrité fonctionnelle.

Vous savez comment transférer la logique métier de la View vers le ViewModel. Vous avez aussi toutes les clés pour valider les tests. La prochaine étape est de simplifier le fichier View et d’intégrer le ViewModel pour une application plus maintenable et performante.

Exemple de certificat de réussite
Exemple de certificat de réussite