So erstellen Sie eine Android- und iOS-App in C# auf einem Mac

Veröffentlicht: 2022-03-11

Es war einmal ein Unternehmen, das die besten Tools hatte, und das Schreiben von Software für ihre Plattform war großartig. Aber langsam wurden sie ihren eigenen Problemen gegenüber gleichgültig. Sie wurden nicht alarmiert, als ihre Systeme zusammenbrachen, sondern akzeptierten diesen Zustand des Universums als eine Tatsache des Lebens. Sie glaubten, dass ihre Programme in sich perfekt seien, heiter und elegant, ihr Zweck selbstverständlich.

Oh Junge, wenn sie nur wüssten, wie falsch sie lagen …

Es war längst überfällig, als sie ihre Fehler erkannten und ihr CEO schrie, alle Entwickler zurückzubringen, die ihre Plattform verlassen und davongesegelt waren. Das Unternehmen war Microsoft und ich war davon überzeugt, dass ihr Schicksal besiegelt war und sie langsam aber sicher von der Spitze der Technologielandschaft verschwinden würden.

Ich bin so froh, dass ich falsch lag!

In den vergangenen Jahren hat Microsoft einige Asse aus dem Ärmel gezaubert. Ja, sie haben Skype vermasselt (dafür hasse ich sie immer noch), sind mit Smartphones gescheitert und mit Tablets fast erfolgreich. Aber sie haben auch einige wirklich erstaunliche Dinge getan. Sie gaben ihren Ansatz des geschlossenen Imperiums auf, öffneten .NET, traten der Linux Foundation bei, veröffentlichten SQL Server für Linux und schufen dieses großartige neue Tool namens Visual Studio für Mac.

Das ist richtig, eine echte Microsoft-IDE, nicht für Windows, sondern für Mac. Stell dir das vor!

Visual Studio für Mac

Schreiben Sie Ihre erste plattformübergreifende Android- und iOS-Anwendung mit C# auf dem Mac

Sie können Visual Studio für Mac verwenden, um fast jeden Anwendungstyp zu erstellen. Es kann iOS, tvOS, Android, Mac, .NET Core oder sogar ASP.NET sein. Da alle coolen Kids jetzt mobile Apps schreiben, sehen wir uns an, was in Visual Studio für Mac nötig ist, um eine C#-Anwendung zu erstellen, die auf Android und iOS ausgeführt werden kann.

Als erstes müssen Sie die Anwendungsvorlage auswählen. Beginnen wir mit einer einfachen „Single View App“.

Einzelansicht-App.

Nachdem Sie den Paketnamen eingegeben und Ihre App gestartet haben, erstellt Visual Studio eine Lösung mit drei Projekten. Das erste Projekt wird eine gemeinsam genutzte Bibliothek sein, in der Sie den plattformunabhängigen Code aufbewahren sollten, und die anderen beiden werden Android- und iOS-Apps sein.

Einstieg.

Sie können das Menü „Ausführen“ oder Befehle in der Anwendungsleiste verwenden, um Ihre App zu starten.

Hallo Welt, klick mich!

Zwei Klicks protokollieren.

Glückwünsche! Sie sind jetzt ein iOS- und Android-Entwickler, ungeachtet der Tatsache, dass Sie nie eine Zeile Objective-C-, Swift- oder Java-Code geschrieben haben.

Wirklich viel erreicht haben wir mit unserer App allerdings noch nicht. Lassen Sie uns die Dinge interessanter machen und Karten und Ortungsdienste integrieren.

Verwenden von Karten und Ortungsdiensten

Denken Sie daran, dass sich VS für Mac noch in der „Vorschau“ befindet und es nicht viel Hilfe und Dokumentation zur Verwendung gibt. Der beste Ort für Referenzen zur Vorgehensweise ist nach wie vor die offizielle Xamarin-Dokumentation.

Visual Studio für Mac verwendet nicht dieselbe Lösungs- und Anwendungsstruktur wie Xamarin-Tools, die Sie möglicherweise auf dem PC gesehen haben. In den meisten Fällen müssen Sie experimentieren und einige Hürden umgehen, damit ihre Beispiele funktionieren. Hoffen wir, dass Microsoft nach der Veröffentlichung der endgültigen Version von VS für Mac an der Spitze bleibt und eine großartige Sammlung von MSDN-Ressourcen bereitstellt.

Anzeige des aktuellen Standorts auf iOS

Für den Zugriff auf Ressourcen von Mobilgeräten, z. B. den aktuellen Standort, müssen Benutzer Ihrer App „manuell“ Berechtigungen erteilen, um diese Ressourcen zu verwenden. iOS verwendet die Datei info.plist , um diese Einstellungen zu speichern. VS für Mac bietet eine visuelle Oberfläche zum Bearbeiten dieser Datei. Als erstes müssen wir einen Wert für die Einstellung namens NSLocationWhenInUseUsageDescription .

Mehrwert für Location When in Usage Description.

Hinweis: VS zeigt einen langen Namen für „NSLocationWhenInUseUsageDescription“ an, wenn Sie den Eigenschaftsnamen festlegen. Dies ist zu erwarten und machen Sie sich keine Sorgen.

Unsere Bootstrap-Anwendung wurde mit einer einfachen Schaltfläche erstellt, die Klicks zählte. Das erste, was Sie tun möchten, ist, es zu entfernen und den Bildschirminhalt durch eine Karte zu ersetzen. Suchen Sie dazu im Lösungsbrowser nach der Datei Main.storyboard und doppelklicken Sie darauf, um sie im Editor zu öffnen.

Ein Storyboard ist eine visuelle Darstellung der Benutzeroberfläche einer Anwendung, die Bildschirme mit Inhalten und die Verbindungen zwischen diesen Bildschirmen zeigt. Ein Storyboard besteht aus einer Sequenz von Szenen, von denen jede einen Ansichtscontroller und seine Ansichten darstellt; Szenen werden durch segue-Objekte verbunden, die einen Übergang zwischen zwei View-Controllern darstellen.

Storyboards werden von Apple eingeführt und auch von Xamarin übernommen. Weitere Informationen finden Sie in der Apple-Dokumentation oder Xamarin-Dokumentation.

Entfernen Sie die Schaltfläche und fügen Sie der Seite eine Map View-Komponente hinzu.

Komponente der Kartenansicht entfernen.

Stellen Sie sicher, dass Sie Ihre „mapView“-Komponente richtig benennen.

Benennen der Map View-Komponente

Jetzt müssen Sie nur noch Ihre ViewController.cs -Datei bereinigen und die ViewDidLoad() Methode so ändern, dass sie mit Folgendem übereinstimmt:

 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; }

Sie können die Funktion „Quick Fix“ verwenden, damit VS automatisch einen Verweis auf die CoreLocation-Bibliothek hinzufügt, oder Sie können ihn manuell hinzufügen.

Nachdem Sie Ihre iOS-App ausgeführt haben, sollten Sie die Aufforderung sehen, auf Ihren Standort zuzugreifen. Sobald die Erlaubnis erteilt wurde, wird Ihre Karte mit einem standardmäßigen blauen Punkt geladen, der anzeigt, wo Sie sich befinden (oder wo Sie mit dem iOS-Simulator vortäuschen :) ).

Standortnutzung in der Anwendung zulassen.

Anzeigen des aktuellen Standorts auf Android

Leider haben Google und Microsoft beschlossen, diese einfache Aufgabe etwas komplizierter zu machen als bei iOS. Um Karten in der Android-Anwendung verwenden zu können, müssen Sie einen Google Maps-API-Schlüssel erstellen und ihn Ihrer AndroidManifest.xml -Datei hinzufügen.

Die Leute von Xamarin haben eine ziemlich einfache Anleitung zum Abrufen eines Google Maps-API-Schlüssels erstellt. Bitte befolgen Sie die Schritte in ihrer Anleitung, bevor Sie fortfahren. Wenn Sie fertig sind, sollte Ihre AndroidManifest.xml eine Einstellung wie diese enthalten:

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

Sie können Ihrer Anwendung jetzt eine Karte hinzufügen.

Das Tolle an VS für Mac ist, dass es von NuGet unterstützt wird, genau wie sein großer Bruder. Da Kartenhandhabungsbibliotheken nicht standardmäßig enthalten sind, müssen Sie das Xamarin.Forms.Maps -Paket installieren.

Installieren Sie Xamarin.Forms.Maps

Es gibt jedoch keine „Kartenansicht“-Komponente, die Sie einfach auf Ihre „Aktivität“ ziehen können. Stattdessen erfordert das Hinzufügen einer Karte zum Bildschirm eine manuelle Änderung Ihrer Datei Resources->layout->Main.axml. Sie können die Designeransicht verwenden, um die zuvor erstellte Schaltfläche zu löschen, wechseln dann aber zur „Codeansicht“ und fügen den folgenden Fragmentcode in Ihr LinearLayout :

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

Wie bei iOS müssen Sie Ihre App so konfigurieren, dass sie nach den richtigen Berechtigungen fragt. Öffnen AndroidManifest.xml zum Bearbeiten und klicken Sie auf die Schaltfläche „Anwendung“ unten links im Editor. VS zeigt Ihnen eine visuelle Oberfläche zum Festlegen dieser Werte. Es gibt einige davon, die Sie aktivieren müssen, wie unten gezeigt.

Berechtigungen aktivieren.

Es ist jetzt an der Zeit, echten Code zu schreiben. Suchen Sie die Datei MainActivity.cs , öffnen Sie sie zur Bearbeitung und nehmen Sie die folgenden Änderungen vor:

Namespace-Referenzen hinzufügen:

 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); } }

Fügen Sie die folgenden beiden Variablen als Variablen auf Klassenebene hinzu:

 LocationManager locMgr; string locationProvider;

Und bereinigen Sie die Methode OnCreate() so, dass sie so aussieht:

 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); }

Durch Aufrufen von GetSystemService innerhalb der Methode OnCreate() wird Ihre MainActivity als ILocationListener aktiviert und kann dadurch alle oben aufgeführten Ereignisse verarbeiten.

Führen Sie Ihre Android-Anwendung aus und Sie sollten die Karte an Ihrem Standort positionieren, ähnlich wie im folgenden Bild.

Karte positioniert in Sarajevo.

Verwenden von Shared Libraries für iOS und Android

Eines der größten Features von VS für Mac ist die Möglichkeit, Code zwischen iOS- und Android-Apps zu teilen. Im Idealfall könnten wir die gesamte Geschäftslogik der App in einer gemeinsam genutzten Bibliothek haben und jeglichen iOS- und Android-spezifischen Code darauf beschränken, Teil der Benutzeroberfläche zu sein.

Lassen Sie uns eine gemeinsam genutzte Klasse erstellen, die eine HTTP-Anforderung asynchron ausführt und den Inhalt in einer Debug-Konsole anzeigt.

Erstellen Sie eine neue Klassendatei in Ihrer gemeinsam genutzten Bibliothek mit dem Namen RestClient.cs mit dem folgenden Code:

(Stellen Sie sicher, dass Sie den richtigen Namensraum aus Ihrem Projekt verwenden.)

 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); } } } }

Verwenden der Bibliothek unter iOS

Ändern Sie Ihre ViewController.cs -Datei im iOS-Projekt so, dass sie mit dem folgenden Code übereinstimmt:

(Stellen Sie sicher, dass Sie den richtigen Namensraum aus Ihrem Projekt verwenden.)

 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. } } }

Führen Sie Ihre iOS-App aus, klicken Sie auf die Schaltfläche und überprüfen Sie die Registerkarte „Anwendungsausgabe“ in Visual Studio. Es sollte so etwas anzeigen:

Registerkarte Anwendungsausgabe.

Verwenden der Bibliothek auf Android

Die für eine Android-App erforderlichen Änderungen sind denen für iOS sehr ähnlich. Ändern Sie die Datei MainActivity.cs so, dass sie mit Folgendem übereinstimmt:

(Stellen Sie sicher, dass Sie den richtigen Namensraum aus Ihrem Projekt verwenden.)

 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); }); } } }

Hinweis: Die Systemarchitektur beider Plattformen, Android und iOS, erfordert, dass alle UI-Interaktionen im Hauptanwendungs-Thread stattfinden. Das bedeutet, dass jede Änderung an UI-Elementen auch innerhalb des Haupt-Threads erfolgen sollte. Hier kommen RunOnUiThread und InvokeOnMainThread ins Spiel. Da HTTP-Requests in einem separaten Thread ausgeführt wurden und doneCallback() außerhalb des Haupt-Threads aufgerufen wurde, mussten wir diese Methoden verwenden, um auf die Schaltflächen zugreifen und die Beschriftung ändern zu können.

C#-Entwickler übernehmen Android und iOS

Visual Studio für Mac hat noch einige Schwachstellen zu beseitigen, aber auf den ersten Blick bin ich sehr gespannt auf seine Zukunft. Der Bedarf an mobilen Anwendungen wächst jeden Tag und mit Visual Studio für Mac hat Microsoft eine Armee großartiger C#-Entwickler dazu befähigt, diesen Bedarf zu decken.

Swift und Java/JVM haben jetzt einen neuen und sehr starken Konkurrenten im Kampf um unsere Entwicklungsumgebungen für mobile Geräte.
Verwandt: .NET Core – Going Wild und Open Source. Microsoft, warum hast du so lange gebraucht?!
Siehe auch: Die Dart-Sprache: Wenn Java und C# nicht scharf genug sind