Chaque OS a ses mécanismes pour lancer une App depuis une autre éventuellement en lui passant des paramètres. Mais qu’en est-il depuis MAUI ?
Les “URI Scheme”
Les “Schémas d’URI” sont des URI comme on en utilise sur le web. Sur ce dernier on doit indiquer le protocole puis un nom de domaine, etc, vous connaissez.
Pour lancer des Apps depuis des Apps il existe dans chaque OS des mécanismes propres. UWP utilise les URI, mais d’autres procédés sont utilisés ou préférés sur Android et iOS en natif tout en supportant tout de même le concept d’URI. Sous MAUI nous essayons toujours d’utiliser le dénominateur commun pour conserver le code le plus cross-plateforme possible et c’est ainsi que les URI se trouvant supportés par les trois OS ce sont eux que nous utiliserons pour naviguer vers d’autres Apps.
Pour rappel un URI (et non “une”) est le signe de Uniform Resource Identifier, soit, “Identifiant de Ressource Universel” (IRU en français mais presque jamais utilisé).
Si vous êtes un peu comme moi et que la plomberie réseau n’est pas votre tasse de thé, que vous ne sautez pas de joie en entendant le mot protocole par exemple, alors il y a des chances que vous ne soyez pas totalement au point avec la nuance entre URI, URL et URN. Alors je vais fixer les choses en quelques mots car pour les détails je renvoie les passionnés de la chose à leur outil de recherche préféré.
URI : Il permet d’identifier une ressource de façon permanente même si cette dernière change de place.
URL et URN sont des URI. Mais l’URL (Uniform Resource Locator, Localisateur de Ressource Universel) en plus d’identifier une ressource (sur un réseau le plus généralement) permet d’obtenir une représentation de la ressource en décrivant son mode d’accès. Une adresse web est un URI qui identifie bien une ressource de façon universelle tout en impliquant une représentation de cette ressource (au format HTML) et en précisant le protocole qui sera utilisé pour un échange (le fameux https en début d’URL).
Les URN quant à eux sont des Uniform Resource Name, Nom de Ressource Universel, des URI qui permettent d’identifier une ressource par son nom à l’intérieur d’un espace de noms. L’URN permet de référencer une ressource sans pour autant fixer son emplacement ni la méthode pour y accéder. L’URN est un concept plus abstrait que l’URL qui est utilisé dans le monde réel pour obtenir des ressources, les manipuler etc… Par exemple un URN valide pourrait-être isbn:978-1-36-734396-2, identifiant d’une ressource de type livre suivant la numérotation de l’International Standard Book Number, ISBN. Grâce à ce numéro vous pouvez faire référence de façon universelle à ce livre, mais l’URN ne dit pas comment il est possible d’obtenir cette ressource. C'est juste un identifiant universel.
Voilà pour les clarifications.
Vous comprenez maintenant pourquoi on parle d’URI et non d’URL ou d’URN (même si on pourrait se dire qu’un URN pour désigner une App serait pas mal. Mais il manquerait d’autres informations, la façon d’y accéder, les paramètres à passer etc).
Le fameux “schéma URI” est celui qui est enregistré dans l’OS par une App pour qu’on puisse l’appeler de l’extérieur. L’idée est celle représentée par le … schéma ci-dessous :

L’exemple donné ici est celui de Skype. Lorsqu’il s’installe sur la device il va indiquer à l’OS un schéma URI appelé “Skype
”. Si vous voulez passer des informations à Skype il faudra envoyer à la plateforme (via une API particulière) un schéma URI compatible de type : skype://
suivi de l’information supportée par ce schéma, ici le numéro de téléphone Skype de la personne à appeler par exemple (skype://555-1111
dans le schéma ci-dessus).
Voilà. Ce qui va nous intéresser maintenant c’est surtout de savoir comment on se sert de ce truc en vrai dans une App MAUI pour en appeler d'autres...
Ouvrir une App externe
Ca va être court… Il suffit d’utiliser :
Device.BeginInvokeOnMainThread(() =>
{
Xamarin.Forms.Device.OpenUri(new Uri("skype://555-1111"));
});
Je rigole... en fait non, mais ça c'était avant... Du temps des Xamarin.Forms. Si je le mentionne ce n'est pas pour le plaisir de la plaisanterie, mais bien parce que nombre de développeurs MAUI viennent des Xamarin.Forms et la compatibilité entre les deux environnements étant si grande qu'on est tenté de ne plus s'interroger sur ce qui a été acquis. Erreur, comme ici. Bien que MAUI soit très proche des Xamarin.Forms, c'est une autre plateforme de développement qui diffère par bien des aspects de son ancêtre.
Nous en avons un exemple frappant ici.
Car il va falloir utiliser une autre classe, le Launcher.
Configuration du Launcher
Pour utiliser le Launcher de .NET MAUI et ouvrir des URI spécifiques dans des applications, des configurations spécifiques aux plateformes sont d"sormais nécessaires sous Android et iOS (sous Windows il n'y a rien à faire). L'App ne pourra en effet qu'appeler les Apps qui auront été listées dans son paramétrage natif. C'est une limitation un peu excessive mais c'est comme cela. Comme le montre un exemple plus bas, il est possible d'invoquer une App depuis un format de fichier qu'elle manipule, dans ce cas il ne semble pas obligatoire de lister l'App même sous Android et iOS (car comment savoir quelle App est enregistrée pour ce type de fichier à l'avance ?).
Android
Ajoutez un intent filter dans le fichier AndroidManifest.xml
:
<activity android:name="appName" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="lyft"/>
<data android:scheme="fb"/>
</intent-filter>
</activity>
iOS/Mac Catalyst
Ajoutez les schémas dans le fichier Info.plist
:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>lyft</string>
<string>fb</string>
</array>
Ouvrir une autre application
Une fois votre App configurée comme indiqué ci-dessus, vous allez pouvoir invoquer les Apps listées par leur schéma URI.
Pour ouvrir une application avec le Launcher
, utilisez la méthode ILauncher.OpenAsync
:
bool supportsUri = await Launcher.Default.CanOpenAsync("lyft://");
if (supportsUri)
await Launcher.Default.OpenAsync("lyft://ridetype?id=lyft_line");
Une version simplifiée peut être réalisée avec TryOpenAsync
:
bool launcherOpened = await Launcher.Default.TryOpenAsync("lyft://ridetype?id=lyft_line");
if (launcherOpened)
{
// Faites quelque chose d'amusant
}
Ouvrir une application via un fichier
Pour ouvrir une application avec un fichier sélectionné :
string popoverTitle = "Read text file";
string name = "File.txt";
string file = System.IO.Path.Combine(FileSystem.CacheDirectory, name);
System.IO.File.WriteAllText(file, "Hello World");
await Launcher.Default.OpenAsync(new OpenFileRequest(popoverTitle, new ReadOnlyFile(file)));
Ici l'App crée un fichier texte File.txt
, y écrit quelques mots, et invoque l'App enregistrée sur la device qui gère les fichiers texte non pas son URI comme précédemment mais par le nom du fichier. C'est l'OS qui choisira l'App adaptée pour traiter ce type de fichier en fonction de ce que l'utilisateur aura installé sur sa machine.
Spécifier l'emplacement du lanceur
Sur iPadOS, vous pouvez spécifier l'emplacement du popover :
await Share.RequestAsync(new ShareFileRequest
{
Title = Title,
File = new ShareFile(file),
PresentationSourceBounds = DeviceInfo.Platform == DevicePlatform.iOS && DeviceInfo.Idiom == DeviceIdiom.Tablet
? new Rect(0, 20, 0, 0)
: Rect.Zero
});
Liste des URI à connaître
Enfin reste un détail : connaître l’URI de l’application à appeler !
Il existe une sorte de registre des URI “officielles” (de nombreuses Apps doivent échapper à ce registre international, comme les Apps "maison" dans les entreprises et certainement d'autres. Là il faudra demander au concepteur le nom de l'URI), il est ici : https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
Même si cette liste est partielle, elle peut aider.
On y retrouve par exemple l’URI de Skype
utilisée dans mes exemples plus haut ainsi que des informations essentielles comme le template (certains template ne sont pas indiqués mais la plupart y sont). Pour Skype donc le template est :
(last updated 2012-09-12)
Resource Identifier (RI) Scheme name: skype
Status: provisional
Scheme syntax:
skype:<username|phonenumber>[?[add|call|chat|sendfile|userinfo]]
Scheme semantics:
Launching Skype call (unofficial; see also callto:)
Encoding considerations:
Unknown, use with care.
Applications/protocols that use this scheme name:
See official documentation from Skype website.
Interoperability considerations:
Unknown, use with care.
Security considerations:
Unknown, use with care.
Contact:
Registering party: Alexey Melnikov <alexey.melnikov&isode.com>
Scheme creator: Skype
Author/Change controller:
Either the registering party or someone who is verified to
represent the scheme creator. See previous answer.
References:
http://en.wikipedia.org/wiki/Skype,
http://www.skype.com/share/buttons/advanced.html
(file created 2012-09-12)
Une fois l’URI connu et le template en poche il devient plus évident de se servir de ce mécanisme.
Conclusion
Il est souvent intéressant de s’ouvrir à l’extérieur, on s’intègre mieux à un écosystème et on s’enrichit, on se rend plus indispensable aussi, et ce qui est valable ici pour un humain l’est aussi pour une App… Si vous gérer des contacts dans votre App, prévoir par une option de pouvoir passer un appel Skype ne coûtera pas grand chose (quelques lignes de C# et un bouton dans l’UI) et tout de suite votre App deviendra vite indispensable à ceux qui utilisent souvent Skype sur les mêmes contacts que ceux manipulés par votre App.
Le bonheur c’est simple comme un coup de fil disait une pub des années 80 pour France Telecom… Le bonheur de vos utilisateurs peut être simple comme un URI…
Pensez-y !
Stay Tuned !