Accesso a funzionalità native con Xamarin.Forms

1. Impostazione dello stage

Quando si tratta di scrivere applicazioni mobili, è importante integrarsi con le funzionalità specifiche della piattaforma che sono disponibili quando ha senso. Ad esempio, se si stesse scrivendo un'app di navigazione, avrebbe senso utilizzare le funzionalità di geolocalizzazione del dispositivo e della piattaforma. Se stavi creando un'app per aiutare le persone con problemi di vista, dovresti integrarti con tutte le funzionalità di sintesi vocale disponibili anche.

Sono gli sviluppatori che sfruttano queste funzionalità per distinguere se stessi e le loro app dagli altri. Queste semplici cose prendono solo un'app normale e la rendono fantastica. Ma cosa succede quando vuoi approfittare di queste funzionalità, ma hai deciso di adottare Xamarin.Forms come meccanismo di scelta multipiattaforma? Devi rinunciare alla speranza su queste funzionalità solo perché hai deciso che la tua app deve essere multipiattaforma e vuoi essere in grado di condividere il maggior numero possibile di codice logico e di interfaccia utente? Assolutamente no.

Questi tipi di domande causano inevitabilmente alcuni problemi per gli sviluppatori che adottano tecnologie più recenti come Xamarin.Forms. Prima del rilascio di Xamarin.Forms, quando lavoravi direttamente con Xamarin.iOS, Xamarin.Android e i modelli di progetto Windows Phone, l'accesso a questi tipi di funzionalità era abbastanza semplice. Dal punto di vista di Xamarin, se si riuscisse a trovare C # di esempio, o persino la lingua nativa e la documentazione dell'SDK, per una particolare funzione, si potrebbe semplicemente mappare il codice ai concetti nativi, perché Xamarin ha fatto un lavoro così spettacolare di tradurre gli stessi concetti nativi su quelle piattaforme in costrutti di linguaggio C #. Le funzionalità di Windows Phone erano ancora più semplici perché non era necessaria alcuna traduzione. Tutto quello che dovevi fare era leggere la documentazione.

Fortunatamente per noi sviluppatori, Xamarin ha dedicato molto tempo e impegno alla progettazione di un meccanismo per consentirci di accedere a queste stesse funzionalità, anche se decidessimo di usare il loro livello di astrazione Xamarin.Forms. Questo meccanismo è conosciuto come il DependencyService.

2. DependencyService Panoramica

A prima vista, un nome come DependencyService può sembrare un po 'intimidatorio. Sembra una terminologia di programmazione elaborata che solo le élite riescono a capire. Se hai mai lavorato con Iniezione di dipendenza (DI) o Inversione del controller (IoC) contenitori, dovresti sentirti a casa con il DependencyService. Se non l'hai fatto, ti assicuro che è un concetto molto semplice da capire una volta scomposto nei suoi componenti.

Qual 'é DependencyService?

Al suo punto di partenza, DependencyService è una classe. È una classe il cui unico scopo dell'esistenza è quello di permetterti di farlo Registrare qualsiasi numero di classi nella tua applicazione. Per registro, voglio dire prendere qualsiasi classe che hai e renderlo noto al servizio. Una volta il DependencyService sa di una classe, può andare e recuperare un'istanza di quella classe ogni volta che è necessario. Questo è l'altro scopo del DependencyService. Se in qualsiasi punto della domanda, decidi di aver bisogno di un'istanza di una classe che è stata registrata nel DependencyService, puoi richiedere o ottenere un'istanza di esso.

Quando si scende veramente nei dadi e bulloni del DependencyService, questa è una generalizzazione molto ampia. Ma dal punto di vista dello sviluppatore, è quasi tutto ciò che devi sapere. Tuttavia, c'è un altro concetto di cui devi essere a conoscenza quando lavori con DependencyService, interfacce. Quando si tratta di DependencyService e tutto questo registrando e recuperando, in genere lo fai rispetto alle interfacce. Ciò significa che quando registri una classe, la stai registrando come implementazione di una particolare interfaccia. E quando stai recuperando un corso, in realtà stai chiedendo il DependencyService per un'implementazione di tale interfaccia. A questo punto, non ti interessa davvero quale sia l'implementazione, vuoi solo una classe che implementa questa interfaccia.

Come fa il DependencyService Lavoro?

Ora che hai una comprensione di base a livello concettuale di ciò che il DependencyService è, scaviamo un po 'più a fondo e vediamo come funziona davvero.

Per usare il DependencyService, hai bisogno di tre cose:

  1. interfacce: Un'interfaccia è semplicemente un costrutto che definisce quali membri devono essere presenti all'interno di qualsiasi classe che sceglie di implementare o accettare questo contratto.
  2. Registrazione: La registrazione è semplicemente il meccanismo di lasciare il DependencyService sapere che una particolare classe desidera essere registrata ed essere in grado di essere recuperata in seguito.
  3. Posizione: Questo concetto è spesso associato a un modello nello sviluppo del software noto come Localizzatore di servizi modello. Questo significa semplicemente che puoi andare in un solo posto, il DependencyService, e richiedere alcune funzionalità, una classe, senza dover istanziare direttamente una nuova istanza.

Analizziamo ciascuno di questi concetti in modo più dettagliato.

3. Interfacce

Le interfacce sono eventi molto comuni nella maggior parte dei linguaggi di programmazione orientata agli oggetti (OOP) al giorno d'oggi. L'utilizzo di un'interfaccia consente di definire un contratto che contiene una serie di proprietà, metodi, eventi, ecc. Che devono essere implementati da qualsiasi classe che accetti tale contratto.

Ecco un esempio molto semplice di un'interfaccia e di una classe che implementa quell'interfaccia.

interfaccia pubblica IFileGrabber string GetFileContents (string fileUri);  public SimpleGrabber: IFileGrabber public string GetFileContents (string fileUri) return GetFileFromFileSystem (fileUri); 

Questo sembra un esempio molto semplice, ma serve allo scopo abbastanza bene. Il IFileGrabber l'interfaccia definisce un singolo metodo, GetFileContents. Il SimpleGrabber la classe accetta o implementa il IFileGrabber interfaccia, il che significa che deve contenere un'implementazione per l'unico metodo.

Ora, invece di dover implementare altro codice nella tua applicazione direttamente contro una classe concreta, SimpleGrabber, puoi iniziare a fare riferimento a IFileGrabber interfaccia invece. Immagina di avere un'altra classe nella tua applicazione simile a questa:

public class DataRetriever private IFileGrabber _fileGrabber; public DataRetriever (IFileGrabber fileGrabber) _fileGrabber = fileGrabber stringa pubblica GetFileContents (string fileUri) return _fileGrabber.GetFileContents (fileUri); 

Usando il IFileGrabber interfaccia invece di una classe concreta, hai la possibilità di creare altri meccanismi per recuperare i file da luoghi diversi e il DataRetriever alla classe non interesserebbe. Supponiamo di avere un'altra classe simile a questa:

public class NetworkGrabber: IFileGrabber public string GetFileContents (string fileUri) return GetFileFromNetwork (fileUri); 

Adesso ti importa meno di come la classe o il GetFileContents il metodo è implementato, è sufficiente sapere che sono presenti almeno i membri definiti nell'interfaccia e che è possibile continuare a codificare utilizzando solo quell'interfaccia come riferimento. Questo è un concetto incredibilmente importante quando si tratta di DependencyService.

4. Registrazione

Nel contesto del DependencyService, Xamarin ha reso abbastanza semplice il processo di registrazione di una classe. Poiché hai già definito la tua interfaccia e almeno una classe che la implementa, puoi registrarla nel DependencyService utilizzando un attributo di assemblaggio molto semplice.

Continuiamo a usare l'esempio sopra e registriamo il SimpleGrabber classe. La definizione della classe sarebbe ora simile a questa:

[assembly: Xamarin.Forms.Dependency (typeof (SimpleFileGrabber))] // Qualsiasi dichiarazione dello spazio dei nomi che possa esistere public SimpleGrabber: IFileGrabber public string GetFileContents (string fileUri) return GetFileFromFileSystem (fileUri); 

Tutto ciò che devi fare è aggiungere il riferimento all'assembly sopra la definizione della classe e al di fuori di qualsiasi definizione di spazio dei nomi che possa essere contenuta all'interno di quel file. Facendo questo semplice compito, avrai registrato con successo il SimpleGrabber classe come implementazione del IFileGrabber interfaccia.

Quando si registra una classe, quella classe deve contenere un costruttore senza parametri in ordine per il DependencyService per istanziarlo. Nel mio esempio precedente, non ho definito un costruttore così il compilatore, per impostazione predefinita, creerà per me un costruttore senza parametri.

5. Posizione

L'ultimo pezzo del puzzle sta ricevendo un'istanza di una classe registrata. Questa è in realtà la parte più semplice dell'intero processo. Per recuperare un'istanza di una classe registrata, è sufficiente utilizzare il DependencyService classe ed è generico Get <> () metodo. Ecco un semplice esempio:

public class FileHelper public string GetFileContents (string fileUri) return DependencyService.Get() .GetFileContents (fileURI); 

In questo caso, in fase di esecuzione, non ti interessa dove il DependencyService sta ottenendo la classe concreta che implementa il IFileGrabber interfaccia. Tutto quello che ti interessa è che la classe implementa il IFileGrabber interfaccia.

6. Utilizzo del DependencyService

Ora che hai una comprensione concettuale di cosa DependencyService è e come usarlo, creiamo una semplice applicazione per metterla in uso.

Per questo esempio, userò Xamarin Studio 5, ma, se lo desideri, puoi utilizzare Visual Studio 2013. Inizia creando una nuova soluzione. Nel Nuova soluzione finestra di dialogo, sotto il C # categoria a sinistra, selezionare il App per dispositivi mobili famiglia di progetto. Sul lato destro, seleziona il App vuota (Xamarin.Forms Portable) o il App vuota (Xamarin.Forms condivisa) modello di progetto. Il codice e l'applicazione risultante saranno gli stessi indipendentemente dal modello scelto.

In questo esempio, userò il Libreria di classi portatile (PCL) versione del modello. Dai un nome al progetto. Chiamerò la soluzione e il primo progetto DependencyServiceSample. Quindi fare clic su ok pulsante.

Questo processo creerà tre progetti separati:

  • DependencyServiceSample - Libreria condivisa (PCL)
  • DependencyServiceSample.Android - Progetto Android
  • DependencyServiceSample.iOS - progetto iOS

Xamarin Studio non supporta la creazione di progetti Windows Phone. Se si utilizza Visual Studio, questo processo creerà quattro progetti. Creerà i tre progetti sopra menzionati e un progetto Windows Phone denominato DependencyServiceSample.WinPhone.

Nella libreria condivisa (DependencyServiceSample), creare un nuovo file di interfaccia e denominarlo ISampleInterface e dargli la seguente implementazione:

namespace DependencyServiceSample interfaccia pubblica ISampleInterface string GetData (); 

È un file di interfaccia standard che definisce un semplice metodo chiamato GetData che restituirà a stringa. Ancora una volta, il punto importante da comprendere è che dal punto di vista del file di codice condiviso, non interessa quale sia l'implementazione di questa interfaccia. L'unica cosa che conta è che qualunque implementazione sia fornita per questa interfaccia, ha un metodo chiamato GetData che restituirà a stringa.

Successivamente, modifichiamo il App.cs file per utilizzare il DependencyService per ottenere un'istanza di ISampleInterface da utilizzare nella tua app Xamarin.Forms. Modifica il  GetMainPage metodo per apparire come il seguente:

Pagina statica pubblica GetMainPage () return new ContentPage Content = new Label Text = DependencyService.Get() .GetData (), VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.CenterAndExpand,,; 

Si noti che l'unica differenza è che il Testo proprietà del Etichetta è stato modificato nella seguente riga:

DependencyService.Get() .GetData ()

In questo modo, stai usando il DependencyService classe e il generico Get <> () metodo per recuperare qualsiasi implementazione del ISampleInterface è implementato nel progetto specifico della piattaforma attualmente in esecuzione. Una volta che l'istanza è stata recuperata, si sta chiamando il GetData metodo per recuperare una stringa e impostare il Testo proprietà del Etichetta.

L'ultimo passaggio ha due parti (tre se si utilizza Visual Studio). A questo punto, sarà necessario implementare il ISampleInterface interfaccia in tutti i progetti specifici della piattaforma nella soluzione.

Iniziamo nel DependencyServiceSample.Android applicazione. Tutto ciò che devi fare è creare un nuovo file di classe nel progetto e assegnargli un nome che ti piace. Ho chiamato il mio Sample_Android. Sostituisci l'implementazione predefinita con quanto segue:

usando il sistema; utilizzando DependencyServiceSample.Android; [assembly: Xamarin.Forms.Dependency (typeof (Sample_Android))] spazio dei nomi DependencyServiceSample.Android public class Sample_Android: ISampleInterface #region ISampleInterface implementazione stringa pubblica GetData () return "Vengo dal progetto Android!";  #endregion 

Questa è una classe semplice che implementa il ISampleInterface interfaccia e la sua implementazione è semplicemente restituire a stringa affermando che proviene dal progetto Android. L'unica differenza è l'uso del montaggio attributo nella parte superiore del file che registri questa classe con il DependencyService in modo che possa essere recuperato in seguito.

Ora, creiamo un'altra implementazione di questa interfaccia nel progetto iOS. Crea una nuova classe nel progetto iOS, nominala Sample_iOS, e sostituire l'implementazione predefinita con quanto segue:

usando il sistema; utilizzando DependencyServiceSample.iOS; [assembly: Xamarin.Forms.Dependency (typeof (Sample_iOS))] spazio dei nomi DependencyServiceSample.iOS public class Sample_iOS: ISampleInterface #region ISampleInterface implementazione stringa pubblica GetData () return "Sono arrivato dal progetto iOS!";  #endregion 

L'implementazione è esattamente la stessa della versione per Android, tranne per il fatto che restituisce una stringa diversa affermando che questa volta proviene dal progetto iOS. Il passo finale è eseguire l'applicazione e vedere se stai ottenendo il risultato che ti aspetti.

Ecco il risultato dell'applicazione iOS in esecuzione.

  

Ecco il risultato dell'applicazione Android in esecuzione.

Come puoi vedere, entrambe le applicazioni funzionano correttamente. Non solo vengono eseguiti, ma vengono eseguiti correttamente da un progetto Xamarin.Forms condiviso che controlla l'interfaccia utente. Da quel codice di interfaccia utente all'interno di Xamarin.Forms, ora sei in grado di immergerti direttamente nei progetti specifici della piattaforma per accedere al codice nativo.

7. Dove andare da qui

Ora che hai le capacità per usare il DependencyService per accedere alle funzionalità native da Xamarin.Forms, il cielo è il limite. Puoi continuare a scrivere semplici implementazioni come hai fatto in questo tutorial o puoi iniziare a sfruttare le funzionalità più interessanti delle piattaforme.

Una delle risorse più interessanti da dare un'occhiata per l'integrazione nel tuo DependencyService è la sezione Ricette del sito Web Xamarin. Qui troverai implementazioni specifiche della piattaforma per ottenere l'accesso a una serie di funzionalità tra cui:

  • Networking
  • Audio
  • video
  • geolocalizzazione
  • Accelerometri

Tutte queste funzionalità sono a tua disposizione quando si tratta di applicazioni Xamarin.Forms. Con il DependencyService, queste caratteristiche possono essere evocate in un momento.

Conclusione

Ora che conosci e comprendi il DependencyService, non è più necessario sentirsi intimiditi quando è necessario accedere a funzionalità specifiche della piattaforma da un'applicazione Xamarin.Forms. Ora possiedi gli strumenti che ti consentono di sfruttare le straordinarie funzionalità native dei dispositivi che ti consentiranno di differenziare le tue app dagli altri negli app store.

Passaggio successivo: guarda il corso

Se desideri ulteriori informazioni su Xamarin, consulta il nostro corso Creazione di app multipiattaforma con C # in Xamarin. 

Nel corso, imparerai come creare un'applicazione multipiattaforma da un singolo codice base che verrà eseguito su tre piattaforme distinte: iOS, Android e Windows Phone 8. Pensa che non può essere fatto? Tra poco lo farai tu stesso. Andiamo a lavorare.

Puoi prendere subito il completamente gratis Prova di 14 giorni di un abbonamento a Tuts +. Dai un'occhiata alle nostre opzioni di abbonamento per iniziare o, se sei interessato a questo corso, puoi acquistarlo singolarmente per $ 15! Ecco un'anteprima per iniziare: