Accesarea caracteristicilor native cu Xamarin.Forms

1. Setarea scenei

Când vine vorba de scrierea de aplicații mobile, este important să se integreze cu caracteristicile specifice platformei care sunt disponibile pentru dvs. când are sens. De exemplu, dacă ați scrie o aplicație de navigare, ar fi logic să utilizați funcțiile de localizare geografică a dispozitivului și a platformei. Dacă creați o aplicație pentru a ajuta persoanele cu deficiențe de vedere, ați dori să vă integrați cu orice funcții de redactare text la vorbire, care erau disponibile și ele.

Dezvoltatorii sunt cei care profită de aceste caracteristici care se fixează pe ei și aplicațiile lor în afară de restul. Aceste lucruri simple iau doar o aplicație obișnuită și o fac minunată. Dar ce se întâmplă atunci când doriți să profitați de aceste caracteristici, dar ați decis să adoptați Xamarin.Forms ca mecanismul tău inter-platformă de alegere? Trebuie să renunți la aceste caracteristici doar pentru că ați decis că aplicația dvs. trebuie să fie încrucișată și doriți să puteți împărtăși cât mai multă logică și cod de interfață utilizator? Absolut nu.

Aceste tipuri de întrebări provoacă inevitabil unele probleme pentru dezvoltatorii care adoptă tehnologii mai noi, cum ar fi Xamarin.Forms. Înainte de lansarea Xamarin.Forms, când lucrați direct cu șabloanele proiectului Xamarin.iOS, Xamarin.Android și Windows Phone, accesarea acestor tipuri de caracteristici a fost destul de simplă. Din perspectiva Xamarin, dacă ați putea găsi un exemplu C # - sau chiar o documentație nativă și o documentație SDK - pentru o anumită caracteristică, ați putea să vă cartografiați codul pe conceptele native, deoarece Xamarin a făcut o treabă atât de spectaculoasă de a traduce aceleași concepte native pe acele platforme în construcții de limbaj C #. Caracteristicile Windows Phone au fost și mai ușoare, deoarece nu a existat o traducere necesară. Tot ce trebuia să faci era să citești documentația.

Din fericire pentru noi ca dezvoltatori, Xamarin a pus mult timp și efort în proiectarea unui mecanism pentru a accesa aceleași caracteristici, chiar dacă alegem să le folosim stratul de abstractizare Xamarin.Forms. Acest mecanism este cunoscut ca DependencyService.

2. DependencyService Prezentare generală

La prima vedere, un nume de genul DependencyService poate părea puțin intimidantă. Suna ca o terminologie de programare fantezistă pe care doar câțiva elită înțeleg. Dacă ați lucrat vreodată Dependența de injecție (DI) sau Inversiunea controlerului (IoC), ar trebui să vă simțiți ca acasă cu DependencyService. Dacă nu ați făcut-o, vă asigur că este un concept foarte simplu de înțeles când o descompuneți în componentele sale.

Ce este DependencyService?

La cel mai simplu lucru, DependencyService este o clasă. Este o clasă a cărei unic scop de existență este să vă permiteți Inregistreaza-te orice număr de clase în întreaga aplicație. Prin înregistrare, vreau să iau orice clasă pe care o ai și să o informați serviciului. Odata ce DependencyService știe despre o clasă, poate merge și poate recupera o instanță a clasei respective ori de câte ori este necesar. Acesta este celălalt scop al DependencyService. Dacă în orice moment al cererii dvs. decideți că aveți nevoie de o instanță a unei clase care a fost înregistrată în DependencyService, puteți solicita sau obține o instanță a acesteia.

Când te duci cu adevărat în jos în piulițele și bolțurile din DependencyService, aceasta este o generalizare foarte largă. Dar din punctul de vedere al dezvoltatorului, asta e aproape tot ce trebuie să știți. Cu toate acestea, există un alt concept pe care trebuie să îl cunoașteți atunci când lucrați cu DependencyService, interfețe. Când vine vorba de DependencyService și toate acestea de înregistrare și de recuperare, de obicei, faci asta în ceea ce privește interfețele. Aceasta înseamnă că, atunci când înregistrați o clasă, o înregistrați ca o implementare a unei interfețe particulare. Și atunci când preiați o cursă, întrebați de fapt DependencyService pentru implementarea interfeței respective. În acest moment, nu vă pasă ce este implementarea, doriți doar o clasă care să implementeze această interfață.

Cum funcționează DependencyService Muncă?

Acum că aveți o înțelegere de bază la un nivel conceptual a ceea ce DependencyService este, să săpăm puțin mai adânc și să vedem cum funcționează.

Pentru a utiliza DependencyService, aveți nevoie de trei lucruri:

  1. interfeţe: O interfață este pur și simplu o construcție care definește ce membri trebuie să fie prezenți în orice clasă care alege să pună în aplicare sau să fie de acord cu acest contract.
  2. Înregistrare: Înregistrarea este doar mecanismul de închiriere DependencyService știți că o anumită clasă dorește să fie înregistrată și să poată fi recuperată mai târziu.
  3. Locație: Acest concept este adesea asociat cu un model de dezvoltare software cunoscut sub numele de Locator de servicii model. Acest lucru înseamnă pur și simplu că puteți merge într-un singur loc, DependencyService, și solicită o anumită funcționalitate, o clasă, fără a trebui să instanțiate în mod direct o nouă instanță.

Să aruncăm în fiecare dintre aceste concepte într-un mod mai detaliat.

3. Interfețe

Interfețele sunt întâlniri foarte frecvente în majoritatea limbilor de programare orientată pe obiecte (OOP) în aceste zile. Utilizarea unei interfețe vă permite să definiți un contract care conține o serie de proprietăți, metode, evenimente etc., care trebuie implementate de orice clasă care este de acord cu acel contract.

Iată un exemplu foarte simplu de interfață și o clasă care implementează acea interfață.

interfața publică IFileGrabber string GetFileContents (string fileUri);  public SimpleGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromFileSystem (fileUri); 

Acest lucru pare a fi un exemplu foarte simplu, dar servește scopului destul de bine. IFileGrabber interfața definește o singură metodă, GetFileContents.  SimpleGrabber clasa este de acord cu sau pune în aplicare IFileGrabber interfață, ceea ce înseamnă că trebuie să conțină o implementare pentru o singură metodă.

Acum, în loc să trebuiască să implementați alt cod în aplicația dvs. direct împotriva unei clase concrete, SimpleGrabber, puteți începe să faceți referire la IFileGrabber interfață în loc. Imaginați-vă că aveți o altă clasă în aplicația dvs. care arată astfel:

clasa publica DataRetriever private IFileGrabber _fileGrabber; public DataRetriever (fișierul IFileGrabberGrabber) _fileGrabber = fileGrabber șirul public GetFileContents (string fileUri) return _fileGrabber.GetFileContents (fileUri); 

Prin utilizarea funcției IFileGrabber în locul unei clase concrete, aveți posibilitatea de a crea alte mecanisme pentru a prelua fișiere din diferite locuri și din DataRetriever clasa nu ar pasa. Să presupunem că avem o altă clasă care arată astfel:

clasa publică NetworkGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromNetwork (fileUri); 

Acum vă pasă mai puțin de modul în care clasa sau GetFileContents metoda este implementată, știți doar că cel puțin membrii care sunt definiți în interfață sunt prezenți și asta înseamnă că puteți continua să codificați folosind doar acea interfață ca referință. Acesta este un concept incredibil de important atunci când este vorba despre DependencyService.

4. Înregistrare

În contextul DependencyService, Xamarin a făcut procesul de înregistrare a unei clase destul de simplu. Deoarece deja ați definit interfața dvs. și cel puțin o clasă care o implementează, puteți să o înregistrați în DependencyService folosind un atribut foarte simplu de asamblare.

Să continuăm să folosim exemplul de mai sus și să înregistrăm SimpleGrabber clasă. Definiția de clasă ar arăta acum în felul următor:

[assembling: Xamarin.Forms.Dependency (typeof (SimpleFileGrabber)]] // orice declarație de spațiu de nume care poate exista public SimpleGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromFileSystem (fileUri); 

Tot ce trebuie să faceți este să adăugați referința de asamblare deasupra definiției de clasă și în afara oricărei definiții de spațiu de nume care poate fi inclusă și în acel fișier. Făcând această sarcină simplă, veți fi înregistrat cu succes SimpleGrabber clasa ca o punere în aplicare a IFileGrabber interfață.

La înregistrarea unei clase, acea clasă trebuie să conțină un constructor fără parametru pentru ca DependencyService să o instanțiați. În exemplul de mai sus, nu am definit un constructor, astfel încât compilatorul va crea, în mod implicit, un constructor fără parametri pentru mine.

5. Locație

Ultimul element al puzzle-ului este obținerea unui exemplu de clasă înregistrată. Aceasta este de fapt cea mai ușoară parte a întregului proces. Pentru a prelua o instanță a unei clase înregistrate, pur și simplu utilizați DependencyService clasă și este generică Get <> () metodă. Iată un exemplu simplu:

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

În acest caz, în timpul rulării, nu vă pasă unde DependencyService este obtinerea de clasa de beton care implementeaza IFileGrabber interfață. Tot ce vă interesează este că clasa implementează IFileGrabber interfață.

6. Utilizarea DependencyService

Acum că aveți o înțelegere conceptuală a ceea ce DependencyService este și cum să-l utilizați, să creați o aplicație simplă pentru a o utiliza.

Pentru acest exemplu, voi folosi Xamarin Studio 5, dar dacă doriți, utilizați Visual Studio 2013. Începeți prin a crea o soluție nouă. În Noua soluție caseta de dialog, în secțiunea C # din stânga, selectați Aplicații pentru mobil familia de proiecte. În partea dreaptă, selectați fie Aplicație Blank (Xamarin.Forms Portable) sau Aplicație Blank (Xamarin.Forms Shared) șablon de proiect. Codul și aplicația rezultată vor fi identice, indiferent de șablonul pe care îl alegeți.

În acest exemplu, voi folosi Biblioteca claselor portabile (PCL) a șablonului. Dați-i un nume proiectului. Voi numi soluția și primul proiect DependencyServiceSample. Apoi faceți clic pe O.K buton.

Acest proces va crea trei proiecte separate:

  • DependencyServiceSample - Bibliotecă comună (PCL)
  • DependencyServiceSample.Android - Proiect Android
  • DependencyServiceSample.iOS - iOS proiect

Studio Xamarin nu acceptă crearea de proiecte Windows Phone. Dacă utilizați Visual Studio, acest proces va crea patru proiecte. Acesta va crea cele trei proiecte de mai sus, precum și un proiect Windows Phone numit DependencyServiceSample.WinPhone.

În biblioteca partajată (DependencyServiceSample), creați un nou fișier de interfață și denumiți-l ISampleInterface și dați-i următoarea implementare:

namespace DependencyServiceSample interfață publică ISampleInterface string GetData (); 

Acesta este un fișier de interfață cu aspect standard care definește o metodă simplă numită Obțineți date care va reveni a şir. Încă o dată, punctul important de înțeles este că, din perspectiva fișierului de cod partajat, nu-i pasă ce arată implementarea acestei interfețe. Singurul lucru care contează este că orice implementare este furnizată pentru această interfață, are o metodă numită Obțineți date care va reveni a şir.

Apoi, modificăm App.cs fișier pentru a utiliza DependencyService pentru a obține o instanță a ISampleInterface pentru a le utiliza în aplicația Xamarin.Forms. Modificați  GetMainPage metoda de a arata dupa cum urmeaza:

pagina statică publică GetMainPage () returnează ContentPage nou Content = new Label Text = DependencyService.Get(), .GetData (), VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.CenterAndExpand,,; 

Observați că singura diferență este că Text proprietate a Eticheta a fost schimbat la următoarea linie:

DependencyService.Get().Obțineți date()

În acest fel, utilizați DependencyService clasa și generic Get <> () - metoda de recuperare a punerii în aplicare a ISampleInterface este implementat în proiectul specific platformei care este în curs de desfășurare. Odată ce acea instanță a fost preluată, îi sunați Obțineți date metoda de a reveni la un șir și a seta Text proprietate a Eticheta.

Ultimul pas are două părți (trei dacă utilizați Visual Studio). În acest moment, va trebui să implementați ISampleInterface interfață în toate proiectele specifice platformei în soluția dvs..

Să începem în DependencyServiceSample.Android cerere. Tot ce trebuie să faceți este să creați un nou fișier de clasă în proiect și să îi dați orice nume doriți. Am numit-o pe a mea Sample_Android. Înlocuiți implementarea implicită cu următoarele:

utilizând Sistemul; folosind DependencyServiceSample.Android; [assembling: Xamarin.Forms.Dependency (typeof (Sample_Android))] namespace DependencyServiceSample.Android clasa publică Sample_Android: ISampleInterface #region ISampleInterface implementare șir public GetData () return "Am venit de la proiectul Android!";  #endregion 

Aceasta este o clasă simplă care implementează ISampleInterface interfața și punerea sa în aplicare este de a returna pur și simplu a şir declarând că vine de la proiectul Android. Singura diferență este utilizarea asamblare atribut în partea de sus a fișierului că registre această clasă cu DependencyService astfel încât să poată fi preluat mai târziu.

Acum, să realizăm o altă implementare a acestei interfețe în proiectul iOS. Creați o nouă clasă în proiectul iOS, denumiți-o Sample_iOS, și înlocuiți implementarea implicită cu următoarele:

utilizând Sistemul; utilizând DependencyServiceSample.iOS; [assembling: Xamarin.Forms.Dependency (typeof (Sample_iOS))] spațiu de nume DependencyServiceSample.iOS public class Sample_iOS: ISampleInterface #region ISampleInterface implementare șir public GetData () return "Am venit din proiectul iOS!";  #endregion 

Implementarea este exact aceeași cu versiunea Android, cu excepția faptului că returnează un șir diferit, care afirmă că acesta vine de data aceasta de la proiectul iOS. Ultimul pas este să rulați aplicația și să vedeți dacă obțineți rezultatul pe care îl așteptați.

Iată rezultatul aplicației iOS care rulează.

  

Iată rezultatul aplicației Android care rulează.

După cum puteți vedea, ambele aplicații funcționează cu succes. Nu numai că rulează, dar rulează cu succes dintr-un proiect Xamarin.Forms partajat care controlează interfața cu utilizatorul. Din acest cod de interfață utilizator în cadrul Xamarin.Forms, acum puteți să vă imersați direct în proiectele specifice platformei pentru a accesa codul nativ.

7. Unde să mergeți de aici

Acum, că aveți abilitățile de a utiliza DependencyService pentru a obține acces la funcționalitatea nativă din Xamarin.Forms, cerul este limita. Puteți continua să scrieți implementări simple, așa cum ați făcut în acest tutorial sau puteți începe să folosiți funcții mai interesante ale platformelor.

Una dintre cele mai interesante resurse pentru a vă uita la integrarea în dvs. DependencyService este secțiunea Rețete a site-ului Xamarin. Aici veți găsi implementări specifice platformei de accesare a unui număr de funcții, inclusiv:

  • Rețele
  • Audio
  • Video
  • Localizarea geografică
  • accelerometre

Toate aceste caracteristici vă stau la dispoziție atunci când vine vorba de aplicațiile Xamarin.Forms. Cu DependencyService, aceste caracteristici pot fi convocate la un moment dat.

Concluzie

Acum că știți și înțelegeți DependencyService, nu mai trebuie să vă simțiți intimidați atunci când aveți nevoie să accesați funcții specifice unei platforme dintr-o aplicație Xamarin.Forms. Acum posedați instrumentele care vă permit să atingeți acele caracteristici uimitoare ale dispozitivelor care vă vor permite în cele din urmă să vă diferențiați aplicațiile de celelalte în magazinele de aplicații.

Următorul pas: Urmăriți cursul

Dacă doriți să aflați mai multe despre Xamarin, verificați cursul pe care l-ați construit Aplicații multi-platformă cu C # în Xamarin. 

În curs, veți învăța cum să creați o aplicație cross-platformă dintr-o bază de cod unică, care va funcționa pe trei platforme diferite: iOS, Android și Windows Phone 8. Credeți că nu se poate face? În doar puțin timp o veți face singur. Sa trecem la treaba.

Puteți să o luați imediat cu un complet gratuit Studiu de 14 zile al unui abonament Tuts +. Aruncati o privire la optiunile noastre de abonament pentru a incepe sau, daca sunteti interesat doar de acest curs, o puteti cumpara individual pentru 15 $! Iată o previzualizare pentru a începe:

Cod