UWP everywhere : Uno
UWP sur iOS et Android : un rêve que j’avais imaginé dès l’annonce du rachat de Xamarin par Microsoft.
La BUILD 2018 arrive enfin et ce n’est pas Microsoft mais une petite société canadienne qui annonce Uno, leur outil interne.
Uno permet d’utiliser le code UWP (XAML et C#) sur Android et iOS. Deux applications playground sont disponibles pour voir le rendu :
– Android
– iOS
Et en bonus, Uno peut aussi créer des application web en générant du code WebAssembly. Cette fonctionnalité est pour l’instant expérimentale et vous pouvez voir une démo ici.
Uno est basé sur la technologie Xamarin. C’est un concurrent à Xamarin Forms mais son approche est très différente : il ne réinvente pas un nouveau XAML, il utilise le XAML et les API d’UWP.
Ici le but est de développer son application directement sur UWP, avec toutes les facilités que les outils Microsoft apportent (XAML live reload, C# Edit & Continue …). Et, une fois le développement fait, on teste si le rendu sur téléphone iOS et Android convient bien.
Pour vous parler d’Uno j’ai décidé de poser directement des questions aux développeurs de la plateforme :
Tout d’abord qui êtes-vous ?
Nous sommes nventive : une société montréalaise qui a été fondée à l’origine pour aider les professionnels à mieux développer sur les technologies .NET. Nous utilisons les technologies C# et XAML depuis notre fondation. On a d’abord commencé en WPF, ensuite WPF/E (devenu Silverlight), suivi de Windows Phone 7 puis WinRT. En parallèle, nous sommes peu à peu devenus une agence de développement d’applications pour la plateforme Windows, tout en conservant nos activités de R&D de développement d’outils et de frameworks.
Par la suite, nos clients nous ont demandé de développer des applications pour d’autres plateformes. Bien sûr, on a fait comme tout le monde: nous avons tenté du développement natif (Objective-C et Java), mais avoir plusieurs équipes qui utilisent des technologies différentes ne nous plaisait pas du tout.
Petit à petit, nous avons porté nos outils maisons en utilisant Mono + Xamarin. Au début, uniquement pour la logique applicative tout en conservant une interface utilisateur spécifique par plateforme, mais nous n’étions pas satisfaits des outils existants et ça nous dérangeait d’avoir des équipes spécialisées par plateforme. Nous avons donc commencé à créer une petite librairie de contrôles qui pourraient être créés en C# et dont le code serait presque identique pour toutes les plateformes. À ce moment, notre but était d’abord et avant tout d’être plus efficace et diminuer l’équipe nécessaire pour faire un projet multiplateformes.
Comme nous avons des clients exigeants et que nos designers sont ambitieux, nous cherchions à obtenir quelque chose qui nous permettait un rendu à la fois flexible et identique sur toutes les plateformes. Il devenait de plus en plus évident que le XAML était le langage qui nous permettait d’atteindre ces objectifs, mais pour le faire il falait non seulement « parser » le XAML, mais également générer du code à la compilation.
Nous avons donc conçu Uno comme une série d’outils « maison » pour adresser notre problématique en attendant que Microsoft nous arrive avec une plateforme vers laquelle nous pourrions migrer. Vous connaissez la suite de l’histoire : aujourd’hui nous ne l’attendons plus, nos outils sont devenus assez efficaces.
Mais qu’est-ce que c’est Uno ?
C’est une série d’outils assemblés ensemble dans le but de reproduire le plus fidèlement possible le comportement de l’interface graphique de Windows UWP XAML sur les autres plateformes tout en bénéficiant des particularités de chacune des plateformes de sorte que le code conçu pour UWP fonctionne de manière presque identique sur les autres plateformes.
Pour convertir une application UWP à utiliser Uno, il suffit de créer les projets iOS, Android et WebAssembly dans la solution et déplacer le code UWP vers un « shared project » pour qu’il soit recompilé sur chacune des plateformes. Ça se fait en quelques minutes.
Comment ça fonctionne en interne ? Utilisez-vous Xamarin Native pour créer les contrôles natifs ?
Nous avons recréé la totalité des APIs de UWP de Windows (version 14393 – Creators Update) et implémenté une partie de ces APIs en fonction de nos besoins sur iOS, Android et WebAssembly. En ce qui concerne les contrôles UWP, tous les éléments visuels (Panels, Buttons, etc..) héritent des classes de primitives de chacune des plateformes afin de s’afficher, tout en adaptant leurs propriétés et les phases de measure et arrange pour se conformer au contrat implicite de UWP.
Schéma de l’architecture d’Uno :
Source : http://platform.uno
Ensuite il y a un générateur de code qui s’exécute à la compilation d’un projet qui utilise Uno et qui prend les fichiers Xaml, les parse et génère le code d’initialisation. Pour ça nous sommes basés sur un composant que nous avons rendu public plus tôt cette année, à savoir le « Uno.SourceGeneration » (https://github.com/nventive/Uno.SourceGeneration).
Prenons le code XAML suivant :
< StackPanel > < TextBlock Text = "Hello world!" Foreground = "{StaticResource MyColor}" /> </ StackPanel > |
Le code généré sera :
new StackPanel { Children = { new TextBlock { Text = "Hello world!" , Foreground = Application.Resources[ "MyColor" ] as Brush, } } } |
Bien sûr il y a également un mode dynamique qui permet de parser du code pendant l’exécution à l’aide du XamlReader (https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Markup.XamlReader). Nous avons donc fait notre implémentation de ce composant qui permet de créer dynamiquement les contrôles pendant l’exécution. C’est d’ailleurs sur ce composant qu’est construit le Uno Playground.
Si je veux utiliser la suite Telerik pour UWP ou le UWP control toolkit sur Uno comment puis-je faire ?
Ça fait un moment que nous avons porté certains contrôles de la suite Telerik avec Uno. Un « fork » du repository de Telerik devrait être rendu public prochainement détaillant la solution.
D’une manière plus générale, la surface d’API de UWP est complètement définie, permettant à n’importe quelle librairie existante d’être compilée presque inchangée sur Uno. La surface d’API de UWP étant particulièrement grande, il se peut que ces librairies s’appuient sur des APIs non implémentées dans Uno. Dans ce cas, il est possible d’utiliser directement la plateforme sous-jacente.
Comment êtes-vous arrivés à rendre UWP utilisable sur iOS et Android ?
De manière itérative, au fur et à mesure que nous en avions besoin pour le développement de nos applications nous avons tenté d’implémenter les API de UWP et de les adapter à la plateforme.
Est-ce possible d’utiliser les rendus natifs de chacune des plateformes ?
Uno supporte la création des contrôles natifs directement dans le XAML au travers du Control Templating, donnant les rendus natifs. Cependant, cette approche réduit la possibilité d’avoir un rendu identique (pixel perfect) très souvent recherché par les designers.
Uno a été construit sur la possibilité d’avoir un mode hybride (xaml vs. natif). Nous avons utilisé cette approche à plusieurs occasions pour utiliser des contrôles disponibles publiquement sans avoir à les réimplémenter. Nous l’avons utilisé pour des contrôles natifs de lecture de vidéos, des carousels, de cartographie et pour intégrer « Lottie » dans certains projets.
Avez-vous des exemples d’application fonctionnant avec Uno ?
Pour le moment, nous avons l’application Gallery (qui contient le “Uno Playground”) de publique, mais nous ne pouvons pas encore dévoiler le nom des applications de nos client pour des raisons de confidentialité.
Avez-vous une roadmap publique ?
Elle n’est pas formalisée encore, car nous voulons jauger la réaction de la communauté pour orienter notre développement.
Combien d’applications avez-vous créées avec Uno ?
Plus de 150.
Combien de temps avez-vous mis à créer Uno ?
Plusieurs années.
Combien de personne travaillent sur Uno actuellement ?
Une dizaine.
Combien de personnes l’utilisent en interne ?
Plus de 75.
Avez-vous été aidé par les équipes de Microsoft pour mettre en place ce Framework ?
Non.
Comment partage-t-on le code entre les différents OS ?
Le plus simple est de faire un « Shared Project » dans Visual Studio et de l’inclure dans toutes les plateformes.
Si c’est un composant, il y a moyen d’utiliser les nouvelles fonctionnalités des projets « dotnet core » qui compilent en simultané vers différentes plateformes.
Nous utilisons déjà cette approche dans le project Uno.Core (https://github.com/nventive/Uno.Core/blob/master/src/Uno.Core/Uno.Core.csproj) qui cible à la fois les plateformes « UAP10.0 », « net46 » et « netstandard2.0 ». Le code de Uno (https://www.nuget.org/packages/Uno.UI) a également ces plateformes comme cibles supplémentaires : « MonoAndroid6.0 », « MonoAndroid7.0 », « MonoAndroid7.1 », « MonoAndroid8.0 » et « Xamarin.iOS1.0 ».
Avez-vous prévu qu’on puisse partager son code via un projet .net standard ?
Non, nous préférons l’approche à base de partage de code source et de classes partielles. Partager les binaires a tendance à compliquer inutilement le développement de code utilisant les particularités de la plateforme.
Si je veux utiliser un contrôle natif d’une plateforme qui n’existe pas en XAML ? Y a-t-il un moyen ?
Il suffit de l’instancier dans le Xaml. Il y a des moyens d’utiliser des alias de namespace pour orienter la génération de code de manière différente selon la plateforme. Il s’agit de XAML conditionnel par plateforme.
Dans le code qui a été publié, vous pouvez voir qu’il y a des préfixes de namespaces du type “<android:XXX>” ou “<ios:XXX>”.
Allez-vous le rendre Open Source ? Avez-vous besoin d’aide ?
Oui nous sommes en train de rendre open source la totalité d’Uno.
Le travail nécessaire pour adapter les différents aspects de la plateforme est colossal. Il y a beaucoup de contrôles, de fonctionnalités qui ne sont pas encore supportées et nous sommes encore en train de chercher une manière qui permettrait à des tiers de fournir des implémentations spécifiques des APIs de UWP. Par exemple, si vous voulez utiliser les APIs pour faire du NFC, ce n’est pas implémenté car nous n’en avons pas eu besoin. Nous voulons que ce soit possible pour des tiers d’en fournir une implémentation.
Ma conclusion
Cette annonce a créé un mini débat dans la communauté Xamarin : Faut-il vraiment un second framework graphique pour Xamarin ?
Pour moi Uno semble beaucoup plus simple que Xamarin Forms, qui demande la création de nombreux renderer.
Or avec Uno, si le visuel d’un contrôle ne convient pas, on peut changer son template comme sur UWP .
On est aussi beaucoup plus proche du rendu : la notion de “Pixel Perfect” – avoir le même rendu au pixel près sur les 3 plateformes – est aussi très intéressante.
Les équipes de Uno ont l’air ultra motivées pour populariser leur outil, les développeurs ayant même pris le temps de répondre à mes questions.
Merci encore à l’équipe d’Uno et tout spécialement à Carl qui a pris du temps à répondre à mes questions.
Personnellement j’ai hâte de tester de plus près cet outil sur une application plus conséquente. Je ne manquerai pas de vous partager mes découvertes.
Happy Coding 😀
Pour aller plus loin :
- Le site officiel de Uno : https://github.com/nventive/Uno
- La démo WASM (uniquement PC en alpha à l’heure où j’écris ces lignes) : http://platform.uno/Playground/index.html
- Le lien vers le Playground : https://github.com/nventive/Uno.Playground
- Développez vos applications multiplateformes pour iOS, Android et Windows
Commentaires