Comment créer une application Android et iOS en C # sur un Mac

Publié: 2022-03-11

Il était une fois une entreprise qui disposait de tous les meilleurs outils, et écrire un logiciel pour sa plate-forme était génial. Mais lentement, ils sont devenus indifférents à leurs propres problèmes. Ils ne se sont pas alarmés lorsque leurs systèmes se sont écrasés, mais ont plutôt accepté cet état de l'univers comme une réalité de la vie. Ils croyaient que leurs programmes étaient parfaits en eux-mêmes, sereins et élégants, leur objectif évident.

Oh mon Dieu, s'ils savaient à quel point ils se sont trompés...

Il était bien trop tard lorsqu'ils ont réalisé leurs erreurs et que leur PDG a pleuré pour ramener tous les développeurs qui ont quitté leur plate-forme et sont partis. L'entreprise était Microsoft et moi, pour ma part, j'étais convaincu que leur sort était scellé et qu'ils périraient lentement mais sûrement de l'avant-garde du paysage technologique.

Je suis tellement content de m'être trompé !

Au cours des dernières années, Microsoft a sorti quelques atouts de sa manche. Oui, ils ont foiré Skype (je les déteste toujours pour ça), ont échoué avec les smartphones et ont presque réussi avec les tablettes. Mais ils ont aussi fait des choses vraiment incroyables. Abandonnant leur approche d'empire fermé, ils ont ouvert .NET, rejoint la Fondation Linux, publié SQL Server pour Linux et créé ce nouvel outil formidable appelé Visual Studio pour Mac.

C'est vrai, un véritable IDE Microsoft non pas pour Windows, mais pour Mac. Imagine ça!

Visual Studio pour Mac

Écrire votre première application Android et iOS multiplateforme à l'aide de C # sur Mac

Vous pouvez utiliser Visual Studio pour Mac pour créer presque n'importe quel type d'application. Il peut s'agir d'iOS, de tvOS, d'Android, de Mac, de .NET Core ou même d'ASP.NET. Comme tous les enfants cools écrivent maintenant des applications mobiles, voyons ce qu'il faut dans Visual Studio pour Mac pour créer une application C # qui s'exécutera sur Android et iOS.

La première chose que vous devez faire est de choisir le modèle d'application. Commençons par une simple « application à vue unique ».

Application à vue unique.

Après avoir renseigné le nom du package et démarré votre application, Visual Studio créera une solution avec trois projets. Le premier projet sera une bibliothèque partagée où vous devrez conserver le code indépendant de la plate-forme, et les deux autres seront des applications Android et iOS.

Commencer.

Vous pouvez utiliser le menu "Exécuter" ou les commandes de la barre d'application pour démarrer votre application.

Bonjour le monde, cliquez sur moi !

Journalisation deux clics.

Toutes nos félicitations! Vous êtes maintenant un développeur iOS et Android, même si vous n'avez jamais écrit une ligne de code Objective-C, Swift ou Java.

Cependant, nous n'avons pas encore accompli grand-chose avec notre application. Rendons les choses plus intéressantes et incorporons des cartes et des services de localisation.

Utilisation des cartes et des services de localisation

Gardez à l'esprit que VS pour Mac est toujours en "Aperçu" et qu'il n'y a pas beaucoup d'aide et de documentation que vous trouverez sur son utilisation. Le meilleur endroit pour des références sur la façon de faire les choses est toujours la documentation officielle de Xamarin.

Visual Studio pour Mac n'utilise pas la même solution et la même structure d'application que les outils Xamarin que vous avez pu voir sur le PC. Dans la plupart des cas, vous devrez expérimenter et contourner quelques obstacles pour que leurs exemples fonctionnent. Espérons que Microsoft restera au top de sa forme et fournira une impressionnante collection de ressources MSDN une fois la version finale de VS pour Mac sortie.

Affichage de l'emplacement actuel sur iOS

L'accès aux ressources de l'appareil mobile, telles que l'emplacement actuel, nécessite que les utilisateurs accordent "manuellement" des autorisations à votre application pour utiliser ces ressources. iOS utilise le fichier info.plist pour stocker ces paramètres. VS pour Mac fournit une interface visuelle pour éditer ce fichier. La première chose que nous devons faire est d'ajouter une valeur pour le paramètre nommé NSLocationWhenInUseUsageDescription .

Ajout de valeur pour l'emplacement lorsque dans la description de l'utilisation.

Remarque : VS affichera un nom long pour « NSLocationWhenInUseUsageDescription » lorsque vous définissez le nom de la propriété. Ceci est prévu et ne vous inquiétez pas.

Notre application bootstrap a été créée avec un simple bouton qui comptait les clics. La première chose que vous voudrez faire est de le supprimer et de remplacer le contenu de l'écran par une carte. Pour ce faire, recherchez le fichier Main.storyboard dans le navigateur de la solution et double-cliquez dessus pour l'ouvrir dans l'éditeur.

Un storyboard est une représentation visuelle de l'interface utilisateur d'une application, montrant des écrans de contenu et les connexions entre ces écrans. Un storyboard est composé d'une séquence de scènes, chacune représentant un contrôleur de vue et ses vues ; les scènes sont reliées par des objets segue, qui représentent une transition entre deux contrôleurs de vue.

Les storyboards sont introduits par Apple et adoptés également par Xamarin. Reportez-vous à la documentation Apple ou à la documentation Xamarin pour plus d'informations.

Supprimez le bouton et ajoutez un composant Map View à la page.

Supprimer le composant Map View.

Assurez-vous de nommer correctement votre composant "mapView".

Nommer le composant Map View

Il ne vous reste plus qu'à nettoyer votre fichier ViewController.cs et à modifier la méthode ViewDidLoad() pour qu'elle corresponde à ce qui suit :

 using CoreLocation; public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. CLLocationManager locationManager = new CLLocationManager(); locationManager.RequestWhenInUseAuthorization(); mapView.ShowsUserLocation = true; }

Vous pouvez utiliser la fonction "Quick fix" pour que VS ajoute automatiquement une référence à la bibliothèque CoreLocation ou vous pouvez l'ajouter manuellement.

Après avoir exécuté votre application iOS, vous devriez voir la demande d'accès à votre emplacement. Une fois l'autorisation accordée, votre carte se chargera avec un point bleu standard indiquant où vous êtes (ou où vous faites semblant d'être en utilisant le simulateur iOS :)).

Autoriser l'utilisation de l'emplacement dans l'application.

Affichage de l'emplacement actuel sur Android

Malheureusement, Google et Microsoft ont décidé de rendre cette tâche simple un peu plus compliquée qu'elle ne l'était avec iOS. Pour utiliser des cartes dans l'application Android, vous devrez créer une clé API Google Maps et l'ajouter à votre fichier AndroidManifest.xml .

Les gars de Xamarin ont créé un guide assez simple pour obtenir une clé API Google Maps. Veuillez suivre les étapes de leur guide avant de continuer. Lorsque vous avez terminé, votre AndroidManifest.xml doit contenir un paramètre comme celui-ci :

 <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR KEY" />

Vous êtes maintenant prêt à ajouter une carte à votre application.

La grande chose avec VS pour Mac est qu'il est alimenté par NuGet, tout comme son grand frère. Comme les bibliothèques de gestion de cartes ne sont pas incluses par défaut, vous devrez installer le package Xamarin.Forms.Maps .

Installer Xamarin.Forms.Maps

Cependant, il n'y a pas de composant "Vue de la carte" que vous pouvez simplement faire glisser vers votre "Activité". Au lieu de cela, l'ajout d'une carte à l'écran nécessite de modifier manuellement votre fichier Resources->layout->Main.axml. Vous pouvez utiliser la vue concepteur pour supprimer le bouton créé auparavant, mais passez ensuite à « Code View » et ajoutez le fragment de code suivant dans votre LinearLayout :

 <fragment xmlns:andro android: android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" />

Comme avec iOS, vous devrez configurer votre application pour demander les autorisations appropriées. Pour ce faire, ouvrez AndroidManifest.xml pour le modifier et cliquez sur le bouton "Application" en bas à gauche de l'éditeur. VS vous montrera une interface visuelle pour définir ces valeurs. Il y en a quelques-uns que vous devrez activer, comme indiqué ci-dessous.

Activation des autorisations.

Il est maintenant temps d'écrire du vrai code. Recherchez le fichier MainActivity.cs , ouvrez-le pour le modifier et apportez les modifications suivantes :

Ajoutez des références d'espace de noms :

 using Android.Gms.Maps.Model; using Android.Gms.Maps; using Android.Locations; Make your MainActivity also a ILocationListener. public class MainActivity : Activity, ILocationListener Implement the ILocationListener methods within your MainActivity: public void OnProviderEnabled(string provider) {} public void OnProviderDisabled(string provider) {} public void OnStatusChanged(string provider, Availability status, Bundle extras) {} public void OnLocationChanged(Android.Locations.Location location) { LatLng latLng = new LatLng(location.Latitude, location.Longitude); CameraPosition.Builder builder = CameraPosition.InvokeBuilder(); builder.Target(latLng); builder.Zoom(15); builder.Bearing(155); builder.Tilt(10); CameraPosition cameraPosition = builder.Build(); CameraUpdate cameraUpdate = CameraUpdateFactory.NewCameraPosition(cameraPosition); MapFragment mapFrag = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.map); GoogleMap map = mapFrag.Map; if (map != null) { map.MoveCamera(cameraUpdate); } }

Ajoutez les deux variables suivantes en tant que variables au niveau de la classe :

 LocationManager locMgr; string locationProvider;

Et nettoyez la méthode OnCreate() pour qu'elle ressemble à ceci :

 protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); locMgr = GetSystemService(LocationService) as LocationManager; Criteria locationCriteria = new Criteria(); locationCriteria.Accuracy = Accuracy.Coarse; locationCriteria.PowerRequirement = Power.Medium; locationProvider = locMgr.GetBestProvider(locationCriteria, true); locMgr.RequestLocationUpdates(locationProvider, 2000, 1, this); }

En appelant GetSystemService depuis la méthode OnCreate() , votre MainActivity sera activée en tant que ILocationListener et pourra ainsi gérer tous les événements répertoriés ci-dessus.

Exécutez votre application Android et vous devriez obtenir la carte positionnée à votre emplacement, similaire à l'image suivante.

Carte positionnée à Sarajevo.

Utilisation des bibliothèques partagées pour iOS et Android

L'une des plus grandes fonctionnalités de VS pour Mac est la possibilité d'avoir du code partagé entre les applications iOS et Android. Idéalement, nous pourrions avoir toute la logique métier de l'application dans une bibliothèque partagée, limitant tout code spécifique iOS et Android à faire partie de l'interface utilisateur.

Créons une classe partagée qui effectuera de manière asynchrone une requête HTTP et affichera le contenu dans une console de débogage.

Créez un nouveau fichier de classe dans votre bibliothèque partagée nommé RestClient.cs avec le code suivant :

(Assurez-vous d'utiliser le bon espace de noms de votre projet)

 using System; using System.Net; namespace testshared { public delegate void callback(string responseText); class ReqState { public ReqState(HttpWebRequest req, callback cb) { request = req; callback = cb; } public HttpWebRequest request { get; set; } public callback callback; } public class RestClient { public RestClient() {} public void FetchPage(string url, callback cb) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.BeginGetResponse(new AsyncCallback(FinishWebRequest), new ReqState(request, cb)); } private void FinishWebRequest(IAsyncResult result) { ReqState reqState = (result.AsyncState as ReqState); HttpWebResponse response = reqState.request.EndGetResponse(result) as HttpWebResponse; using (var reader = new System.IO.StreamReader(response.GetResponseStream())) { string responseText = reader.ReadToEnd(); reqState.callback(responseText); } } } }

Utilisation de la bibliothèque sur iOS

Modifiez votre fichier ViewController.cs dans le projet iOS pour qu'il corresponde au code suivant :

(Assurez-vous d'utiliser le bon espace de noms de votre projet)

 using System; using UIKit; using System.Diagnostics; namespace testshared.iOS { public partial class ViewController : UIViewController { RestClient rest = new RestClient(); public ViewController(IntPtr handle) : base(handle) {} public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. Button.AccessibilityIdentifier = "myButton"; Button.TouchUpInside += delegate { Button.SetTitle("Loading...", UIControlState.Normal); rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { InvokeOnMainThread(() => { Debug.Write(content); Button.SetTitle("All Done", UIControlState.Normal); }); } public override void DidReceiveMemoryWarning() { base.DidReceiveMemoryWarning(); // Release any cached data, images, etc that aren't in use. } } }

Exécutez votre application iOS, cliquez sur le bouton et vérifiez l'onglet "Sortie de l'application" dans Visual Studio. Il devrait afficher quelque chose comme ceci :

Onglet Sortie d'application.

Utilisation de la bibliothèque sur Android

Les modifications nécessaires sur une application Android sont très similaires à celles nécessaires sur iOS. Modifiez le fichier MainActivity.cs pour qu'il corresponde aux éléments suivants :

(Assurez-vous d'utiliser le bon espace de noms de votre projet)

 using Android.App; using Android.Widget; using Android.OS; namespace testshared.Droid { [Activity(Label = "testshared", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : Activity { RestClient rest = new RestClient(); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // Get our button from the layout resource, // and attach an event to it Button button = FindViewById<Button>(Resource.Id.myButton); button.Click += delegate { button.Text = $"Loading..."; rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { RunOnUiThread(() => { Button button = FindViewById<Button>(Resource.Id.myButton); button.Text = "All done"; System.Diagnostics.Debug.WriteLine(content); }); } } }

Remarque : L'architecture système des deux plates-formes, Android et iOS, exige que toutes les interactions de l'interface utilisateur se produisent sur le thread d'application principal. Cela signifie que toute modification des éléments de l'interface utilisateur doit également se produire à partir du thread principal. C'est là RunOnUiThread et InvokeOnMainThread . Étant donné que les requêtes HTTP étaient exécutées dans un thread séparé et que doneCallback() était appelée en dehors du thread principal, nous avons dû utiliser ces méthodes pour pouvoir accéder aux boutons et changer l'étiquette.

Les développeurs C# prennent le contrôle d'Android et d'iOS

Visual Studio pour Mac a encore quelques problèmes à résoudre, mais dès le premier regard, je suis très enthousiaste quant à son avenir. Le besoin d'applications mobiles augmente chaque jour et, avec Visual Studio pour Mac, Microsoft a en outre permis à une armée de grands développeurs C# de répondre à ce besoin.

Swift et Java/JVM ont maintenant un nouveau concurrent très puissant dans la bataille pour nos environnements de développement d'appareils mobiles.
En relation : .NET Core - Going Wild et Open Source. Microsoft, qu'est-ce qui vous a pris si longtemps ? !
En relation : Le langage Dart : lorsque Java et C# ne sont pas assez pointus