Come creare un'app per Android e iOS in C# su un Mac

Pubblicato: 2022-03-11

C'era una volta un'azienda che aveva tutti gli strumenti migliori e scrivere software per la loro piattaforma era fantastico. Ma lentamente, sono diventati indifferenti ai propri problemi. Non si sono allarmati quando i loro sistemi sono andati in crash, ma hanno piuttosto accettato questo stato dell'universo come un dato di fatto. Credevano che i loro programmi fossero perfetti dentro di sé, sereni ed eleganti, il loro scopo evidente.

Oh ragazzo, se solo sapessero quanto si sbagliano...

Era in ritardo quando si sono resi conto dei loro errori e il loro CEO ha pianto per riportare indietro tutti gli sviluppatori che hanno lasciato la loro piattaforma e se ne sono andati. L'azienda era Microsoft e io, per esempio, ero convinto che il loro destino fosse stato segnato e che sarebbero morti lentamente ma inesorabilmente dall'avanguardia nel panorama tecnologico.

Sono così felice di essermi sbagliato!

Negli ultimi anni, Microsoft ha tirato fuori alcuni assi dalla manica. Sì, hanno incasinato Skype (lo odio ancora per questo), hanno fallito con gli smartphone e sono quasi riusciti con i tablet. Ma hanno anche fatto cose davvero incredibili. Abbandonando il loro approccio all'impero chiuso, hanno aperto .NET, si sono uniti alla Linux Foundation, hanno rilasciato SQL Server per Linux e hanno creato questo nuovo fantastico strumento chiamato Visual Studio per Mac.

Esatto, un vero IDE Microsoft non per Windows, ma per Mac. Immaginalo!

Visual Studio per Mac

Scrivere la tua prima applicazione multipiattaforma per Android e iOS usando C# su Mac

Puoi usare Visual Studio per Mac per creare quasi tutti i tipi di applicazioni. Può essere iOS, tvOS, Android, Mac, .NET Core o anche ASP.NET. Poiché tutti i ragazzi fantastici stanno scrivendo app per dispositivi mobili, vediamo cosa serve in Visual Studio per Mac per creare un'applicazione C# che verrà eseguita su Android e iOS.

La prima cosa che devi fare è scegliere il modello dell'applicazione. Iniziamo con una semplice "App a visualizzazione singola".

App a visualizzazione singola.

Dopo aver inserito il nome del pacchetto e aver eseguito il bootstrap dell'app, Visual Studio creerà una soluzione con tre progetti. Il primo progetto sarà una libreria condivisa in cui dovresti mantenere il codice indipendente dalla piattaforma e gli altri due saranno app Android e iOS.

Iniziare.

Puoi utilizzare il menu "Esegui" o i comandi nella barra dell'applicazione per avviare l'app.

Ciao mondo, cliccami!

Registrazione di due clic.

Congratulazioni! Ora sei uno sviluppatore iOS e Android indipendentemente dal fatto che non hai mai scritto una riga di codice Objective-C, Swift o Java.

Tuttavia, non abbiamo ancora realizzato molto con la nostra app. Rendiamo le cose più interessanti e incorporiamo mappe e servizi di localizzazione.

Utilizzo di mappe e servizi di localizzazione

Tieni presente che VS per Mac è ancora in "Anteprima" e non c'è molto aiuto e documentazione che troverai sull'utilizzo. Il posto migliore per i riferimenti su come eseguire le cose è ancora la documentazione ufficiale di Xamarin.

Visual Studio per Mac non usa la stessa soluzione e struttura dell'applicazione degli strumenti Xamarin che potresti aver visto nel PC. Nella maggior parte dei casi, dovrai sperimentare e aggirare alcuni ostacoli per far funzionare i loro esempi. Speriamo che Microsoft rimanga al passo con il proprio gioco e fornisca una straordinaria raccolta di risorse MSDN una volta rilasciata la versione finale di VS per Mac.

Visualizzazione della posizione corrente su iOS

L'accesso alle risorse del dispositivo mobile, come la posizione corrente, richiede agli utenti di concedere "manualmente" le autorizzazioni alla tua app per utilizzare tali risorse. iOS usa il file info.plist per memorizzare queste impostazioni. VS per Mac fornisce un'interfaccia visiva per la modifica di questo file. La prima cosa che dobbiamo fare è aggiungere un valore per l'impostazione denominata NSLocationWhenInUseUsageDescription .

Valore aggiunto per Posizione quando in Descrizione utilizzo.

Nota: VS mostrerà un nome lungo per "NSLocationWhenInUseUsageDescription" quando si imposta il nome della proprietà. Questo è previsto e non ti preoccupare.

La nostra applicazione bootstrap è stata creata con un semplice pulsante che contava i clic. La prima cosa che vorrai fare è rimuoverlo e sostituire il contenuto dello schermo con una mappa. Per fare ciò, cerca il file Main.storyboard nel browser della soluzione e fai doppio clic su di esso per aprirlo nell'editor.

Uno storyboard è una rappresentazione visiva dell'interfaccia utente di un'applicazione, che mostra schermate di contenuto e le connessioni tra queste schermate. Uno storyboard è composto da una sequenza di scene, ognuna delle quali rappresenta un controller di visualizzazione e le sue viste; le scene sono collegate da oggetti segue, che rappresentano una transizione tra due controller di visualizzazione.

Gli storyboard sono introdotti da Apple e adottati anche da Xamarin. Per ulteriori informazioni, fare riferimento a Documentazione Apple o Documentazione Xamarin.

Rimuovere il pulsante e aggiungere un componente Visualizzazione mappa alla pagina.

Rimuovi il componente Vista mappa.

Assicurati di nominare correttamente il tuo componente "mapView".

Denominazione del componente Vista mappa

Tutto ciò che resta ora è pulire il tuo file ViewController.cs e modificare il metodo ViewDidLoad() in modo che corrisponda a quanto segue:

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

Puoi usare la funzione "Correzione rapida" per fare in modo che VS aggiunga automaticamente un riferimento alla libreria CoreLocation oppure puoi aggiungerlo manualmente.

Dopo aver eseguito la tua app iOS dovresti vedere la richiesta di accedere alla tua posizione. Una volta concessa l'autorizzazione, la mappa verrà caricata con un punto blu standard che mostra dove ti trovi (o dove stai fingendo di essere utilizzando il simulatore iOS :)).

Consenti l'utilizzo della posizione nell'applicazione.

Visualizzazione della posizione corrente su Android

Sfortunatamente, Google e Microsoft hanno deciso di rendere questo semplice compito un po' più complicato di quanto non fosse con iOS. Per utilizzare le mappe nell'applicazione Android, dovrai creare la chiave API di Google Maps e aggiungerla al tuo file AndroidManifest.xml .

I ragazzi di Xamarin hanno creato una guida piuttosto semplice per ottenere una chiave API di Google Maps. Si prega di seguire i passaggi nella loro guida prima di procedere. Quando hai finito, il tuo AndroidManifest.xml dovrebbe contenere un'impostazione come questa:

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

Ora sei pronto per aggiungere una mappa alla tua applicazione.

La cosa grandiosa di VS per Mac è che è alimentato da NuGet, proprio come il suo fratello maggiore. Poiché le librerie di gestione delle mappe non sono incluse per impostazione predefinita, sarà necessario installare il pacchetto Xamarin.Forms.Maps .

Installa Xamarin.Forms.Maps

Tuttavia, non esiste un componente "Vista mappa" che puoi semplicemente trascinare nella tua "Attività". Invece, l'aggiunta di una mappa allo schermo richiede la modifica manuale del file Resources->layout->Main.axml. Puoi utilizzare la vista designer per eliminare il pulsante creato in precedenza, ma poi passare a "Vista codice" e aggiungere il seguente codice frammento nel tuo LinearLayout :

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

Come con iOS, dovrai configurare la tua app per richiedere le autorizzazioni appropriate. Per fare ciò, apri AndroidManifest.xml per la modifica e fai clic sul pulsante "Applicazione" nella parte in basso a sinistra dell'editor. VS ti mostrerà un'interfaccia visiva per impostare questi valori. Ce ne sono alcuni che dovrai abilitare, come mostrato di seguito.

Abilitazione delle autorizzazioni.

Ora è il momento di scrivere del codice reale. Trova il file MainActivity.cs , aprilo per la modifica e apporta le seguenti modifiche:

Aggiungi riferimenti allo spazio dei nomi:

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

Aggiungi le seguenti due variabili come variabili a livello di classe:

 LocationManager locMgr; string locationProvider;

E ripulisci il metodo OnCreate() in modo che assomigli a questo:

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

Chiamando GetSystemService dall'interno del metodo OnCreate() , il tuo MainActivity verrà attivato come ILocationListener e sarà quindi in grado di gestire tutti gli eventi sopra elencati.

Esegui la tua applicazione Android e dovresti posizionare la mappa sulla tua posizione, simile all'immagine seguente.

Mappa posizionata a Sarajevo.

Utilizzo delle librerie condivise per iOS e Android

Una delle maggiori caratteristiche di VS per Mac è la possibilità di avere codice condiviso tra app iOS e Android. Idealmente, potremmo avere tutta la logica aziendale dell'app in una libreria condivisa, limitando qualsiasi codice specifico per iOS e Android a far parte dell'interfaccia utente.

Creiamo una classe condivisa che eseguirà in modo asincrono una richiesta HTTP e mostrerà il contenuto in una console di debug.

Crea un nuovo file di classe nella tua libreria condivisa denominato RestClient.cs con il codice seguente:

(Assicurati di utilizzare lo spazio dei nomi corretto dal tuo progetto)

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

Utilizzo della Libreria su iOS

Modifica il tuo file ViewController.cs nel progetto iOS in modo che corrisponda al codice seguente:

(Assicurati di utilizzare lo spazio dei nomi corretto dal tuo progetto)

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

Esegui la tua app iOS, fai clic sul pulsante e seleziona la scheda "Output dell'applicazione" in Visual Studio. Dovrebbe visualizzare qualcosa del genere:

Scheda Output dell'applicazione.

Utilizzo della Libreria su Android

Le modifiche necessarie su un'app Android sono molto simili a quelle necessarie su iOS. Modificare il file MainActivity.cs in modo che corrisponda a quanto segue:

(Assicurati di utilizzare lo spazio dei nomi corretto dal tuo progetto)

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

Nota: l'architettura di sistema di entrambe le piattaforme, Android e iOS, richiede che tutte le interazioni dell'interfaccia utente avvengano sul thread dell'applicazione principale. Ciò significa che qualsiasi modifica agli elementi dell'interfaccia utente dovrebbe avvenire anche all'interno del thread principale. È qui che entrano in gioco RunOnUiThread e InvokeOnMainThread . Poiché le richieste HTTP sono state eseguite in un thread separato e doneCallback() è stato chiamato al di fuori del thread principale, abbiamo dovuto utilizzare questi metodi per poter accedere ai pulsanti e modificare l'etichetta.

Gli sviluppatori C# stanno rilevando Android e iOS

Visual Studio per Mac ha ancora alcune rughe da risolvere, ma dal primo sguardo sono molto entusiasta del suo futuro. La necessità di applicazioni mobili cresce ogni giorno e, con Visual Studio per Mac, Microsoft ha ulteriormente consentito a un esercito di grandi sviluppatori C# di soddisfare questa esigenza.

Swift e Java/JVM ora hanno un nuovo e molto forte concorrente nella battaglia per i nostri ambienti di sviluppo di dispositivi mobili.
Correlati: .NET Core - Going Wild e Open Source. Microsoft, perché ci hai messo così tanto?!
Correlati: Il linguaggio Dart: quando Java e C# non sono abbastanza nitidi