Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Ajouter le partage de données à vos Apps UWP

Copier / coller c’est le minimum, mais partager c’est le must ! Masi comment implémenter le partage de données dans une App UWP ?

Les bases du partage

Le minimum pour une application évoluant dans un environnement collaboratif tel que Windows est d’implémenter correctement le copier / coller. Bien entendu la plupart des contrôles de saisie gère cela automatiquement désormais, mais au final cela fait très peu alors que ces fonctions deviennent vraiment intéressantes quand elles ont une granularité plus grande. Par exemple si chaque champ d’une fiche client gère tout seul le copier/coller de base, il est particulièrement intéressant de fournir une commande permettant de copier toute l’adresse par exemple. Cela se fait via un menu contextuel ou un bouton et vos utilisateurs seront ravis de pouvoir écrire dans Word un courrier au client en question en copiant d’un bloc toute l’adresse plutôt que de faire des tas d’allers-retours entre votre App et Word pour chaque champ… C’est à ce genre de détail qu’on reconnait immédiatement une application professionnelle bien pensée.

Je vous ai présenté dans un article du mois d’aout comment implémenter ce type de comportement en jouant avec le presse-papiers de UWP (

UWP / WinRT : utiliser le presse-papiers).

Tout cela est le minimum syndical de la coopération inter-applications sous Windows.

Mais depuis Windows 8 d’autres pré-requis en matière d’UX se sont imposés. Notamment le partage de données.

Sous Windows 8 et WinRT ces nouvelles fonctions de collaboration ont fait leur apparition sous diverses formes dont la plus voyante était la barre de Charmes.

Hélas les utilisateurs n’ont pas trouvé de … charme à Windows 8 et le retour à un bureau classique sous Windows 10 a entrainé la disparition de cette barre. Mais heureusement pas des avancées en matière d’UX qu’elle apportait !

Partager n’est pas copier

imageOn peut se demander s’il y a une différence fondamentale entre la fonction “copier” et celle de partage sous Windows 10. Les deux permettent d’échanger des données sous plusieurs format (texte, rtf, html, images…), les deux peuvent s’initier depuis l’application et le résultat, la chose copiée ou partagée, sera disponible dans l’application réceptrice.

C’est dans cette dernière que tout se joue…

La fonction “copier” est générique, elle place la chose copiée dans le presse-papiers qui est disponible pour toute application déjà lancée ou qui sera lancée ultérieurement et tant qu’une autre ne viendra pas changer le contenu du presse-papiers. L’utilisateur peut ainsi appeler l’application cible, la mettre à l’avant-plan et coller les données partagées à l’endroit qu’il désire. il peut même copier la même chose dans dix applications à la suite. C’est pratique (et même indispensable) mais ce n’est pas une fonction très conviviale. Elle a ce côté “rustique” du DIY …

Car si “copier” permet de distribuer (de coller) des données à la volée un peu partout l’utilisateur raisonne le plus souvent d’une façon différente, il pense finalité, action complète.

Ce que tout utilisateur voudra et préfèrera plutôt un scénario complet visant à effectuer une tâche sophistiquée d’un seul coup : j’ai un texte à l’écran que je veux envoyer en mail à un collaborateur, je clique sur le bouton “Partager” de l’application et là j’ai le choix de plusieurs applications réceptrices possibles, qu’elles soient déjà chargées ou non, je choisi le gestionnaire de mail et là un nouveau mail est créé avec son corps déjà rempli. Je n’ai plus qu’à taper les premières lettres du mail du destinataire et faire “envoyer” et je reviens à mon application de départ comme si rien ne s’était passé et sans me soucier de diminuer ou fermer l’application de mail… C’est un scénario complet qui vise une action spécifique réalisée comme un tout cohérent.

C’est donc effectivement une sorte de “copier/coller” mais avec une UX d’un niveau largement plus évolué et ciblant une application qui ne sera pas vue en entier, juste la partie utile pour recevoir des données (la page de saisie d’un mail et non pas tout le gestionnaire de mail) et qui disparaitra une fois le partage effectué. Laissant l’utilisateur se concentrer sur ce qu’il fait et non pas sur la façon de le faire.

C’est là que se trouve la différence fondamentale entre “copier” et “partager”.

Implémenter le partage

Avec ou sans barre de Charmes le partage existe donc toujours car les avancées de Windows 8 étaient réelles. Mal présentées, surtout sur PC, mais bien réelles.

Microsoft a revu sa copie et Windows 10 prend le meilleur des deux mondes. Ce n’est plus un OS à deux têtes (d’où en partie l’échec annoncé de Windows 8 à mon sens) mais un OS avec une tête unique et bien remplie.

Si on retrouve un bureau classique à la Windows 7 on y retrouve néanmoins les avancées de WinRT et Windows 8 et le partage en fait partie. Il existe des différences dans la mise en œuvre mais vu le peu d’applications WinRT en circulation je suppose que personne n’a eu le temps de “prendre des habitudes” et donc cela ne gène pas beaucoup (il faut savoir tirer le positif de toute situation, même d’un échec !).

Le principe est d’une grande simplicité : en général depuis un bouton ou un menu contextuel ou une barre de commande, l’utilisateur déclenche le mode de partage. A ce moment l’application est sollicitée par l’OS pour retourner les données. Simple et efficace.

Se déclarer prêt à partager

La première des choses à faire pour l’application qui souhaite supporter le partage de données c’est de se déclarer à l’OS. En réalité il ne s’agit vraiment d’une déclaration (qui irait donc dans le sens App vers OS) mais d’un abonnement où on déclare un délégué qui prendra en charge l’évènement de partage quand il interviendra (donc plutôt un sens OS vers App).

Cette déclaration fait intervenir le DataTransferManager et son évènement DataRequested. On s’abonne ici comme à n’importe quel évènement :

DataTransferManager.GetForCurrentView().DataRequested += myShareHandler;

On remarque l’utilisation intermédiaire de GetForCurrentView() qui obtient l’instance du gestionnaire de transfert pour la vue active.

Une fois cela effectué l’application (la vue concernée en fait) est prête à recevoir les demandes de partage qui viendront de l’OS.

Mais c’est l’utilisateur qui en réalité initie le processus et ce depuis l’application qui partage ses données… Il faut donc prévoir un bouton ou autre pour lancer le processus.

Déclencher le partage

En général c’est en réponse à une action de l’utilisateur que se déclenche le partage. Donc depuis un clic sur un bouton, un menu  contextuel ou autre. Mais rien n’interdit l’application de lancer le partage de sa propre initiative. On peut imaginer une tâche en plusieurs étapes qui se termine forcément par un partage. Il n’y a donc pas d’obligation dans le fait que ce soit l’utilisateur qui initie le mécanisme.

Le déclenchement s’effectue comme suit :

DataTransferManager.ShowShareUI();

Difficile de faire plus simple puisque l’opération est statique et directement invocable depuis la classe du gestionnaire de transfert.

Répondre et partager

L’application s’est abonnée à l’évènement de partage, elle propose aussi un moyen d’initier ce dernier. Mais comment répond-t-elle à la demande ?

C’est dans le gestionnaire de l’évènement que l’App va recevoir tout le nécessaire via l’argument de type DataRequestedEventArgs. Elle va pouvoir récupérer un objet déjà existant “Request” qui lui permettra de spécifier les données partagées, de donner un titre au partage (obligatoire) ainsi qu’une description plus fournie (optionnelle).

Si la barre de Charmes a disparu le principe visuel reste le même et une barre de partage va apparaitre sur le côté droit de l’écran. Le titre du partage sera affiché avec la description optionnelle puis une liste d’applications compatibles suivra. Un clic sur l’une d’entre-elle entrainera le transfert des données que l’OS aura donc déjà reçu. L’utilisateur peut annuler l’opération en cliquant ailleurs sur l’écran ou par toutes les méthodes de “dismiss” disponibles selon la device utilisée. Car rappelons-nous que la différence essentielle entre Windows 10 et Windows 8 tient bien plus dans UWP, plateforme indépendante de l’OS et multi form factors, que dans les nuances de look & feel. Le partage fonctionne et existe sous UWP cela signifie qu’il fonctionne sur toutes les machines faisant tourner Windows 10 et suivants.

La compatibilité ascendante étant conservée entre Windows 8 et Windows 10 les applications qui utilisaient la barre de Charmes et les mécanismes WinRT bénéficient bien entendu du même service. Notamment elles se voient adjoindre automatiquement un menu Hamburger possédant les principales commandes comme Search, Share et Settings. Il n’y a donc de rupture que dans l’aspect et non dans le fond. Et c’est tant mieux car dans le fond Windows 8 n’était pas mauvais… juste maladroitement trop disruptif et mal adapté aux PC.

Le code qui permet de répondre à l’évènement est le suivant :

void myShareHandler(DataTransferManager sender, 
                                   DataRequestedEventArgs args)
{
   if(!string.IsNullOrEmpty(DataToShare))
   {
      args.Request.Data.SetText(DataToShare);
      args.Request.Data.Properties.Title =
                    Windows.ApplicationModel.Package.Current.DisplayName;
   }
   else
   {
      args.Request.FailWithDisplayText("There is nothing to share!");
   }
}

Ci-dessus on retrouve la méthode enregistrée plus haut pour gérer le partage. Elle se contente ici de partager du texte brut contenu dans une propriété fictive DataToShare de type string.

Le titre est le nom du package courant (le package étant l’entité englobant l’application lorsqu’elle est envoyée au Store). Ce n’est qu’un exemple et il sera préférable en réalité de proposer un titre en rapport avec les données partagées ainsi qu’une description détaillant ces données.

On remarque enfin que si les données à partager sont vides nous en informons l’OS en définissant un message par le biais de FailWithDisplayText(string). Le simple fait de renseigner ce texte plutôt que de les données (Request.Data) fera échouer le transfert et l’utilisateur recevra le message prévu. C’est ergonomique et nul besoin d’afficher un Toast par exemple.

Et voilà, c’est tout ce qu’il faut savoir pour partager… Ce n’est rien et partager rend heureux celui qui donne et celui qui reçoit, c’est bien connu !

Enfin c’est “presque” tout car je vous invite à regarder la documentation ad hoc pour utiliser d’autres options que SetText() qui transfère du texte brut. On peut échanger des images, du RTF, du HTML etc.

Partage et MVVM

Il y a peu à dire sur le sujet… Juste qu’il faut que le code qui gère l’évènement soit toujours en mémoire lorsque celui-ci interviendra, ce qui semble naturel. Mais l’OS se charge de ce problème car il existe un DataTransfermanager pour chaque fenêtre de l’application. Celle qui est active recevra l’évènement uniquement si elle y est abonnée. Pas de risque donc que Page1 s’abonne et  que Page2 étant affichée page1 qui n’est plus chargée la reçoive (avec le plantage qu’on imagine).

De fait on le placera le code de partage soit dans le Shell pour une application qui fonctionne selon ce modèle ou bien il faudra s’abonner dans chaque vue de l’application qui propose le partage.

Mais où placer le code puisqu’on parle de “vue” ?

En réalité c’est bien la vue active qui est concernée mais comme sous MVVM elle ne possède pas de code (sauf d’UI) c’est son ViewModel qui prendra tout cela en charge. Tout le code montré ici peut donc sans problème y être placé, aucune obligation que cela soit le code-behind qui s’en charge. Et cela semble logique puisque c’est lui qui va fournir les données à partager. Ce n’est donc pas une opération purement liée à la vue seule mais à la vue en tant que tout fonctionnel (donc incluant son ViewModel).

Conclusion

Partager n’est donc pas “copier” et encore moins “coller”. Si ces fonctions en sont les lointains ancêtres le partage sous UWP est une avancée ergonomique qui rend les applications pour cette plateforme plus collaboratives et ce avec des manœuvres simples et standardisées pour l’utilisateur lui offrant une UX plus satisfaisante et plus cohérente.

Si implémenter un copier/coller intelligent est toujours une bonne idée, y ajouter le partage est un minimum pour une application UWP. Rappelez-vous que bien que très proches ces fonctions sont très différentes. Le partage appelle et lance éventuellement une partie seulement de l’application cible mais pas l’application entière alors que le copier/coller peut intervenir n’importe où dans une application même hors d’un dialogue spécifique. Le partage est une action complète et unique de haut niveau, “copier/coller” est plus générique et plus frustre à la fois.

Il y a donc complémentarité et non concurrence dans cette association binaire où plutôt qu’un yin & yang que tout semble opposer il faut y voir une symbiose visant une UX de meilleure qualité.

Windows 10 fait monter la pression d’un cran sur le développeur en l’obligeant à prendre en considération de nouvelles normes, de nouveaux réflexes qui s’ajoutent aux bonnes pratiques déjà acquises. Mais il ne faut pas y voir une lubie de Microsoft, juste une nécessité imposée par les utilisateurs devenus très exigeants depuis qu’ils ont tous en poche un smartphone… appareil simple et puissant où l’UX est devenue une arme de différenciation entre OS et applications bien plus que la technique… Et quand on mange tous les jours chez Maxim's il devient difficile en rentrant chez soi de trouver l’appétit pour une simple boite des raviolis fades et mollassons…

Rester un dinosaure ou bien voir ici l’occasion de se renouveler tant techniquement qu’intellectuellement est la seule question qui se pose réellement pour le développeur…

Stay Tuned !

blog comments powered by Disqus