Vérifier les données du glisser-déposer iOS sur un Mac cloud

DevOps et CI/CD ·~7 min de lecture

Vérifier les données du glisser-déposer iOS sur un Mac cloud

Avant une mise en production, l’équipe a fait glisser un identifiant de tâche depuis une liste vers une zone d’édition. L’aperçu du glisser-déposer était correct et le dépôt n’a déclenché aucune erreur, mais la valeur enregistrée était une chaîne vide. Le problème ne venait pas de l’animation : si le type de données déclaré par la source, celui accepté par la cible ou le moment où se termine la lecture asynchrone ne concordent pas, l’interface peut donner une fausse impression de réussite. Lorsqu’on travaille à distance sur un Mac cloud, mieux vaut d’abord vérifier le contrat de données avec XCTest, puis ouvrir le simulateur pour valider le geste réel. Ces deux vérifications ne sont pas interchangeables.

Définir un contrat de glisser-déposer vérifiable

Pour chaque type de contenu déplaçable, consignez trois éléments : l’UTType déclaré par le fournisseur, les types acceptés par la cible et le contenu attendu après une lecture réussie. Si, par exemple, un identifiant de tâche doit simplement être collé sous forme de chaîne dans un champ de texte, les deux côtés peuvent convenir d’utiliser UTType.utf8PlainText. Il ne faut pas enregistrer du texte brut côté source, ne rechercher que des types d’image côté cible, puis considérer que « l’action de dépôt a eu lieu » suffit à prouver la réussite.

Précisez aussi les cas d’échec : un type non pris en charge ne doit pas mettre en évidence la cible comme disponible ; une lecture échouée ne doit pas insérer une tâche vide ; l’annulation d’un déplacement ne doit pas modifier les données d’origine. Si l’application doit conserver d’autres champs que l’identifiant de tâche, définissez un format de données dédié que les deux côtés savent analyser, au lieu de dissimuler des données structurées dans le texte affiché.

La fin d’un dépôt est un événement d’interface, pas une validation des données. Ne mettez à jour l’état de l’application que si les types correspondent, que la lecture asynchrone réussit et que le contenu est validé.

Vérifier le type et les données reçues avec XCTest

Ajoutez un fichier de test à la cible de tests de l’application. Le fournisseur ci-dessous enregistre du texte UTF-8. Le test vérifie d’abord le type, attend le rappel de lecture, puis contrôle les octets reçus. Il n’a besoin ni d’une souris ni d’un bureau graphique : c’est donc un contrôle rapide à intégrer au pipeline de build.

import XCTest
import UniformTypeIdentifiers

final class DragPayloadTests: XCTestCase {
    func testPlainTextPayload() {
        let provider = NSItemProvider()
        provider.registerDataRepresentation(
            forTypeIdentifier: UTType.utf8PlainText.identifier,
            visibility: .all
        ) { completion in
            completion(Data("ticket-42".utf8), nil)
            return nil
        }

        XCTAssertTrue(provider.hasItemConformingToTypeIdentifier(
            UTType.plainText.identifier
        ))
        XCTAssertFalse(provider.hasItemConformingToTypeIdentifier(
            UTType.image.identifier
        ))

        let loaded = expectation(description: "Load drag payload")
        provider.loadDataRepresentation(
            forTypeIdentifier: UTType.utf8PlainText.identifier
        ) { data, error in
            XCTAssertNil(error)
            XCTAssertEqual(data.flatMap { String(data: $0, encoding: .utf8) },
                           "ticket-42")
            loaded.fulfill()
        }
        wait(for: [loaded], timeout: 5)
    }
}

Ici, plainText sert à vérifier la compatibilité du type, tandis que utf8PlainText permet de lire la représentation précise qui a été enregistrée. Une fois le test réussi, reprenez les mêmes contrôles de type et la même logique de décodage dans le code de l’application. Sinon, le test pourrait accepter un type alors que l’interface utilise une autre liste de types autorisés. Le code de production doit aussi gérer error, les données vides et les échecs de décodage UTF-8 dans le rappel. Ne modifiez pas l’interface sur la seule base de hasItemConformingToTypeIdentifier.

Choisir une destination de simulateur avant de lancer le test

Commencez par vérifier les configurations disponibles dans la console VMCommit. Une fois le Mac mis à disposition, connectez-vous en SSH et consultez la liste des simulateurs installés. Remplacez le projet, le Scheme et l’identifiant d’appareil ci-dessous par vos propres valeurs. Récupérez l’identifiant avec la première commande : la chaîne d’exemple ne correspond pas à un appareil réel.

xcrun simctl list devices available
xcodebuild -list -project App.xcodeproj
xcodebuild test \
  -project App.xcodeproj \
  -scheme App \
  -destination 'platform=iOS Simulator,id=YOUR_DEVICE_ID' \
  -only-testing:AppTests/DragPayloadTests

Le chemin de -only-testing doit correspondre à la cible de tests et au nom de classe du projet. Si la commande indique que le Scheme n’existe pas, vérifiez d’abord qu’il est partagé. Si l’appareil choisi n’est pas disponible, relisez la liste sur ce Mac au lieu de réutiliser l’identifiant d’une autre machine. En cas d’échec, conservez la sortie brute pour distinguer « le simulateur n’a pas démarré » de « l’assertion sur les données reçues a échoué ».

Valider le dépôt réel dans une session graphique

Le test du contrat ne passe pas par la gestion des gestes : il ne peut donc pas prouver que UIDragInteraction ou UIDropInteraction est correctement raccordé. Ouvrez le simulateur sur le bureau graphique, installez l’application de test, puis effectuez la séquence complète suivante :

  1. Appuyez longuement sur un élément source valide et commencez à le déplacer. Vérifiez que l’aperçu correspond à l’élément sélectionné.
  2. Passez sur une cible autorisée et vérifiez qu’elle indique la possibilité de déposer l’élément. Passez ensuite sur une zone qui n’accepte pas ce type et confirmez que ce retour visuel disparaît.
  3. Déposez l’élément, attendez la fin de la lecture, puis vérifiez que le bon identifiant de tâche apparaît une seule fois dans la zone d’édition.
  4. Commencez un autre déplacement et annulez-le avant le dépôt. Vérifiez que ni la liste ni la zone d’édition ne changent.

Pour les données volumineuses, traitez « lecture en cours » comme un état distinct : empêchez les validations répétées et ne mettez à jour le contenu qu’une fois la lecture terminée. En cas d’échec, rendez l’interface de nouveau utilisable et affichez un message explicite. N’affichez pas « Importé » avant le retour du rappel asynchrone simplement pour rendre l’animation plus fluide. La vérification graphique porte sur les changements d’état visibles par l’utilisateur ; XCTest porte sur les données sous-jacentes. Consignez les deux résultats séparément.

Suivre le flux de données pour diagnostiquer un échec

Si la cible ne se met pas en évidence, commencez par les types. Dans l’environnement de développement, affichez les identifiants enregistrés par la source et ceux autorisés par la cible. Vérifiez que le code teste la compatibilité des types, et non la seule égalité des noms affichés. Si la cible se met en évidence mais qu’aucun contenu n’apparaît, vérifiez que le rappel de chargement s’exécute, puis examinez l’erreur, la taille des données et le résultat du décodage. N’écrivez pas l’intégralité des données dans des journaux partagés : le contenu des tâches peut renfermer des données métier, et le type ainsi que la taille suffisent généralement à localiser le point de défaillance.

Si le contenu est parfois inséré deux fois, vérifiez si le modèle est mis à jour à la fois dans le rappel de dépôt et dans celui de fin de chargement, ou si une lecture est lancée plusieurs fois pour le même fournisseur. Attribuez un identifiant d’opération à chaque dépôt et ne validez qu’une seule fois, après vérification. Écartez tout résultat en attente en cas d’annulation ou d’échec. Lorsque vous ajoutez d’autres données, comme des images, écrivez des tests distincts pour chaque type accepté. La réussite du test de texte brut ne garantit pas le fonctionnement de tous les parcours de glisser-déposer.

Vérifier les deux relevés de résultats avant la livraison

Le relevé des tests automatisés doit couvrir la correspondance des types, le rejet des types non pris en charge, l’exactitude des octets, la gestion des valeurs vides et des erreurs de lecture, ainsi que l’échec du test en cas d’expiration du délai. Le relevé des vérifications graphiques doit couvrir la justesse de l’aperçu à la source, le bon retour visuel sur la cible, une seule mise à jour après réussite, l’absence de modification après annulation et un message d’échec qui n’annonce pas à tort une réussite. Exécutez les premiers à chaque commit ; reprenez particulièrement les secondes après une modification de l’interaction ou de la version du système.

Enfin, répétez l’opération dans un simulateur vierge pour vérifier que le résultat ne dépend pas du contenu laissé dans la zone d’édition par une exécution précédente. Conservez la liste des types effectivement acceptés par le projet avec ces deux relevés. Lors du prochain changement de format du glisser-déposer, ils permettront de déterminer si le problème vient du contrat de données, de la lecture asynchrone ou du retour visuel du geste.

Questions fréquentes

Un test NSItemProvider suffit-il à valider l’interface ?

Non. Il valide le type et la lecture des données ; l’aperçu, la cible et l’annulation doivent être contrôlés dans l’interface.

Quand l’application réceptrice doit-elle lire les données ?

Vérifiez d’abord que le UTType est accepté, puis chargez la représentation de façon asynchrone. N’indiquez pas la fin de l’import avant le résultat.

Louez selon vos besoins

Validez votre prochaine étape sur un Mac mini physique dédié

VMCommit propose des Mac mini M4 physiques dédiés, disponibles à la journée, à la semaine, au mois ou au trimestre. Choisissez un modèle et un emplacement, puis consultez les disponibilités en temps réel dans la console.

Louer un Mac mini