Lucrul în rețea a devenit mai ușor cu AFNetworking

Lucrul în rețea este greu. Există diverse părți în mișcare implicate și mulți factori trebuie să fie luați în considerare pentru a face să funcționeze. Din fericire, o serie de biblioteci open-source au apărut de-a lungul timpului pentru a facilita crearea de rețele. AFNetworking, creată și întreținută de oamenii din Gowalla, este o astfel de bibliotecă. Acest tutorial vă va prezenta cadrul AFNetworking, prezentând, de asemenea, modul în care puteți interoga API-ul iTunes Store!

În acest tutorial, vă prezint AFNetworking și vă arăt o privire asupra a ceea ce această bibliotecă are de oferit. După ce ați petrecut câteva minute cu această bibliotecă, veți observa că a fost proiectat cu ușurință în utilizare în minte. Acesta nu numai că va accelera dezvoltarea, dar va avea și grijă de multe sarcini de rețea. Vom construi o aplicație simplă care va întreba iTunes Store pentru filmele care se potrivesc cu termenul de căutare "harry". Rezultatele interogării noastre vor fi afișate într-o vizualizare de tabel.


Sumarul proiectului

Aplicația pe care intenționăm să construim interogări API-ul de căutare iTunes Store Search. În special, căutăm iTunes Store pentru filme care se potrivesc cu termenul de căutare "harry". Dacă interogarea noastră are succes, procesăm rezultatele și le afișăm într-o vizualizare de tabel. Fiecare rând reprezintă un film cu un titlu, un regizor și o miniatură care prezintă opera de artă a filmului. Gata? Să începem.


Setarea proiectului

Înainte de a ne murdări mâinile cu AFNetworking, trebuie să construim o fundație de bază. Aceasta înseamnă configurarea proiectului nostru, crearea unei vizualizări de tabel și adăugarea unei vizualizări a indicatorului de activitate. Vom afișa indicatorul de activitate atunci când cererea noastră este procesată de magazinul iTunes. Acest lucru va da utilizatorului o valoare suplimentară valoroasă de feedback care este adesea trecute cu vederea.

Creați un nou proiect în Xcode selectând Vizualizare individuală șablon din lista de șabloane. Denumiți aplicația NetworkingIsFun, introduceți un identificator al companiei, setați "iPhone" pentru familia de dispozitive și debifați "Utilizați tablouri de articole". Puteți lăsa restul neatins, dar asigurați-vă că Utilizați numărarea automată a referințelor este bifat. Spuneți Xcode unde doriți să vă salvați proiectul și apăsați pe "Salvați".


Adăugarea vizualizărilor pentru tabel și indicatorul de activitate

Chiar dacă Interface Builder este mare, îmi construiesc interfețele programat adesea, și asta vom face și în acest tutorial. Aceasta ne va permite să ne concentrăm doar asupra codului fără a fi distras de Interface Builder. Deschis ViewController.h și să creeze trei variabile de instanță (ivars), precum și proprietăți pentru aceste ivars. Deoarece vom lucra cu o vizualizare de tabel, nu uitați să vă faceți controlerul de vizualizare conform cu UITableViewDataSource și UITableViewDelegate protocoale. Fișierul de antet al controlerului de vizualizare ar trebui să pară asemănător celui de mai jos:

 #import  @ interfață ViewController: UIViewController  UITableView * _tableView; UIActivityIndicatorView * _activityIndicatorView; NSArray * _movies;  @property (nonatomic, reține) UITableView * tableView; @property (nonatomic, reține) UIActivityIndicatorView * activityIndicatorView; @property (nonatomic, reține) filmele NSArray *; @Sfârșit

Dacă sunteți confuz de utilizarea sublinierilor, vă recomand să citiți aici. Simțiți-vă liber să omiteți sublinierile dacă credeți că arată urât sau vă face să vă simțiți incomod. În afară de sublinieri, nu ar trebui să existe surprize. Declarăm UITableView și UIActivityIndicatorView, precum și un NSArray, pe care îl vom folosi pentru a stoca rezultatele pe care le primim din interogarea noastră de căutare. Gata? Să ne îndreptăm spre fișierul de implementare al controlorului nostru de vizualizare.

Deoarece am declarat trei proprietăți în fișierul antetului nostru, trebuie să le sintetizăm accesorii ViewController.m. Din nou, dacă sublinierii te confundă, le poți lăsa afară.

 @synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView, filme = _movies;

În a noastră viewDidLoad , am stabilit opiniile privind tabelul și indicatorul de activitate. Codul de mai jos ar trebui să fie explicabil în cea mai mare parte. Dacă nu ați configurat niciodată o vizualizare de tabel fără a utiliza Interface Builder, este posibil să vedeți câteva linii care nu vă cunosc. În locul cablării tabelului de vizualizare în Interface Builder, avem grijă de acest lucru în viewDidLoad metodă. După ce a sunat la superclajul " viewDidLoad , inițiazăm vizualizarea tabelului cu un cadru și un stil și ne-am stabilit controlerul de vizualizare ca sursă de date și delegat al vizualizării noastre de tabel. Când se lansează aplicația noastră, ascundem vizualizarea tabelului, deoarece nu avem nimic de afișat atâta timp cât interogarea noastră nu a returnat niciun rezultat. Înainte de a adăuga vizualizarea de tabel ca subiectiv la vizualizarea controlerului nostru de vedere, am setat masca de autorezonare. Masca de autorezonare definește modul în care vizualizarea tabelă ar trebui redimensionată dacă vizualizarea părinte - vizualizarea controlerului de vedere la care adăugăm vizualizarea de tabelă - modifică dimensiunea. Acest lucru se întâmplă atunci când dispozitivul este rotit, de exemplu. Confuz? Nu vă faceți griji. Nu este important pentru această aplicație.

 - (vid) viewDidLoad [super viewDidLoad]; // Configurarea vizualizării tabelului self.tableView = [[UITableView aliniere] initWithFrame: CGRectMake (0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height) stil: UITableViewStylePlain]; self.tableView.dataSource = auto; self.tableView.delegate = auto; auto.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.tableView.hidden = DA; [self.view addSubview: self.tableView]; // Configurarea indicatorului de activitate Vizualizare autoactivitateIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray]; autoactivitateIndicatorView.hidesWhenStopped = DA; auto.activitateIndicatorView.center = auto.view.center; [self.view addSubview: self.activityIndicatorView]; [self.activityIndicatorView startAnimating]; // Inițierea sursei de date self.movies = [[NSArray alloc] init]; 

Setarea afișării indicatorului de activitate este la fel de ușor. Inițializăm vizualizarea indicatorului de activitate cu un stil predefinit, setați-l hidesWhenStopped proprietate la DA, și poziționați-o în centrul vederii sale părinte. După adăugarea acesteia la vizualizarea controlerului de vizualizare, începem să animăm indicatorul de activitate. Indicatorul de activitate se va afișa automat de la setarea acestuia hidesWhenStopped proprietate la YES.

La sfârșitul anului viewDidLoad , inițializăm filme matrice. Vom folosi mai târziu pentru a stoca rezultatele interogării noastre de căutare.


Vizualizarea protocoalelor de tabel

Pentru acest tutorial, vom implementa doar două metode ale protocolului sursă de date pentru tabele. Sunt necesare ambele metode. Aceasta este implementarea minimă necesară pentru a începe vizualizarea tabelului. Chiar dacă am stabilit controlorul nostru de vizualizare ca delegat al tabelului, nu vom folosi niciuna dintre metodele delegate în aplicația noastră. Dacă ați folosit o vizualizare de tabelă înainte, nu veți găsi surprize în implementările de metode prezentate mai jos.

 - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectiunea if (self.movies && self.movies.count) return self.movies.count;  altceva return 0;  - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath NSString static * cellID = @ "Cell Identifier"; UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: cellID]; dacă (! cell) celula = [[UITableViewCell alocare] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: cellID];  retur; 

În tableView: numberOfRowsInSection:, trebuie să returnați numărul de rânduri din fiecare secțiune a vizualizării de tabel. În exemplul nostru, vizualizarea tabelului conține o singură secțiune (implicită), ceea ce face totul mai ușor. Mai întâi verificăm dacă ne filme variabila nu este zero și verificăm că ea conține elemente. Dacă ambele dintre aceste cerințe sunt îndeplinite, vom returna numărul de elemente din matricea filmelor, dacă nu, vom reveni la zero.

Al nostru tableView: cellForRowAtIndexPath: metoda este de asemenea fundamentală. Începem să ne întrebăm dacă există o celulă pe care o putem reutiliza. Dacă nu este cazul, vom crea o celulă nouă cu un identificator de stil și reutilizare. Încheiem implementarea noastră prin returnarea celulei noastre. Acest lucru va face pentru moment. Acum puteți să vă creați și să executați aplicația. Dacă ați urmat corect pașii, ar trebui să vedeți indicatorul de activitate care se rotește ca nebun, iar vizualizarea tabelului ar trebui ascunsă.


Adăugarea AFNetworking la Mix

Adăugarea AFNetworking la proiectul dvs. este ușor ca plăcintă. Începeți prin descărcarea bibliotecii de la GitHub și extragerea arhivei. Arhiva contine un folder numit AFNetworking, care conține fișierele sursă pe care trebuie să le includem în proiectul nostru. Glisați întregul dosar în proiectul dvs. Xcode și asigurați-vă că verificați Copiați articolele în dosarul grupului de destinație (dacă este necesar) și adăugați și fișierele sursă la țintă.

După adăugarea bibliotecii AFNetworking în proiectul dvs., construiți și executați aplicația și urmăriți ca totul să se destrame. Ce sa întâmplat cu proiectul nostru? De ce primim toate aceste avertismente și erori? Când am creat proiectul nostru Xcode, am activat Numărătoarea automată a referințelor (ARC). La momentul redactării, biblioteca AFNetworking nu utilizează ARC. Nu vă faceți griji, totuși, putem folosi această bibliotecă îngrijită cu foarte puține eforturi. Tot ce trebuie să faceți este să spuneți compilatorului că toate fișierele sursă ale bibliotecii AFNetworking nu utilizează ARC. Asta e.

Cum facem asta? Selectați proiectul în Project Navigator și selectați țintă. Apasă pe Construiți faze în navigația de sus și deschideți Sursa de compilare sertar. Acest tabel vă prezintă toate fișierele sursă pe care compilatorul le va compila la momentul compilării. Coloana din stânga afișează numele fișierelor, iar coloana din dreapta afișează pavilioanele despre care compilatorul ar trebui să știe.

Puteți vedea aceste steaguri ca instrucțiuni sau mesaje pentru compilator. Tot ce trebuie să faceți este să adăugați un semnalizator compilator la fiecare fișier sursă al bibliotecii AFNetworking. Pentru aceasta, selectați un fișier sursă din listă și faceți dublu clic pe celula din coloana din dreapta. Va apărea o fereastră mică în care puteți adăuga unul sau mai multe drapele compilatoare. În cazul nostru, pur și simplu tastați -fno-objc-arc și faceți clic pe Terminat. Acest steag spune compilatorului că fișierul sursă nu utilizează ARC. Asigurați-vă că adăugați acest steag la toate cele zece fișiere sursă ale bibliotecii AFNetworking.


Solicitarea interogării API-ului Search Store iTunes Store

AFNetworking este o bibliotecă care poate face multe pentru dvs., dar astăzi vom folosi doar două caracteristici bune. Înainte de a începe să folosim clasele AFNetworking, trebuie să adăugăm următoarea instrucțiune de import chiar sub prima declarație de import din fișierul de implementare a controlerului de vizualizare.

 #import "AFNetworking.h"

Această declarație de import ne va permite accesul la toate clasele AFNetworking. Mergeți înapoi la controlerul nostru de vizualizare viewDidLoad și adăugați următorul fragment imediat după inițializarea filme mulțime.

 NSURL * url = [[NSURL alocare] initWithString: @ "http://itunes.apple.com/search?term=harry&country=us&entity=movie"]; NSURLRequest * request = [Alocare NSURLRequest] initWithURL: url]; AFJSONRequestOperation * operație = [AFJSONRequestOperation JSONRequestOperationWithRequest: cerere succes: ^ (NSURLRequest * request, NSHTTPURLResponse * răspuns, id JSON) NSLog (@ "% @", JSON);  eșec: ^ (NSURLRequest * cerere, răspuns NSHTTPURLResponse *, eroare NSError *, id JSON) NSLog (@ "Solicitare eronată:% @,% @", eroare, error.userInfo); ]; [start start];

Permiteți-mi să vă explic ce se întâmplă. În prima linie, creăm NSURL pentru solicitarea noastră. Șirul pe care îl folosim în procesul de inițializare este conform formatului așteptat de API-ul Căutării magazinului iTunes Store. Sintaxa API-ului de căutare este destul de simplă: Termenul pe care îl căutăm este "harry", ne restricționăm căutarea în iTunes Store din SUA și căutăm numai filme. Ușor, corect?

Apoi, inițializăm o NSURLRequest și trecem în NSURL pe care tocmai l-am creat. Apoi AFNetworking intră. AFNetworking conține câteva clase foarte specializate care fac munca noastră foarte ușoară. Cel pe care îl folosim aici este AFJSONRequestOperation. Aceasta este o clasă concepută pentru a prelua și analiza datele JSON în fundal. După cum sugerează și numele, această clasă este o subclasă a NSOperation sau, mai precis, una dintre superclasele acestei clase moșteneste de la NSOperation. Clasa vă permite să preluați datele solicitate și analizează, de asemenea, răspunsul JSON. Aceasta înseamnă că nu trebuie să ne ocupăm de JSON-ul brut. Datele pe care le returnează sunt gata de utilizare în aplicația dvs. AFNetworking utilizează parserul JSON încorporat pe iOS 5 și revine la propriul parser JSON pentru versiunile mai vechi de iOS.

Utilizarea AFJSONRequestOperation este ușor deoarece are o singură metodă de clasă. Această metodă de clasă acceptă trei argumente: (1) un NSURLRequest, (2) un bloc de succes, executat atunci când cererea este reușită și (3) un bloc de eroare, executat atunci când cererea eșuează. Dacă blocurile sunt noi pentru dvs. sau nu vă simțiți confortabil să le folosiți, atunci vă recomand să citiți tutorialul lui Collin Ruffenach despre blocuri și enumerare pe Mobiletuts +. Blocul de succes are trei argumente: (1) NSURLRequest, (2) răspunsul NSHTTPURL al cererii noastre și (3) un obiect JSON analizat. Blocul de defecțiuni este aproape identic. Singura diferență este că este nevoie de un argument suplimentar, un NSError care conține mai multe informații despre ce sa întâmplat în caz că cererea noastră nu reușește.

În scopuri de testare, logăm obiectul JSON analizat pentru a vedea ce ne trimite API-ul de căutare iTunes Store Search. În plus, înregistrăm și eroarea în blocul de eșec în cazul în care cererea noastră se întâmplă să eșueze. Înainte de a construi și a rula aplicația noastră încă o dată, trebuie să începem operația sunând start pe obiectul nostru de operare. Construiți și rulați aplicația dvs. și aruncați o privire la ieșirea din consola.

Dacă totul a mers bine, veți vedea rezultatele solicitării noastre înregistrate în consola. Obiectul JSON analizat este un dicționar cu două chei: (1) RESULTCOUNT, care conține numărul de rezultate returnate și (2) numărul actual rezultate ca o serie de dicționare. Am notat doar răspunsul la consola pentru a vedea dacă cererea noastră a avut succes, acum putem vedea cheile pentru fiecare element din matricea rezultatelor. Vom avea nevoie de aceste chei pentru a afișa unele informații în tabelul nostru.


Populând vizualizarea tabelului

Suntem gata să prezentăm rezultatele din tabelul nostru. Înlocuiți instrucțiunea de jurnal din blocul de succes cu fragmentul prezentat mai jos. Începem prin atribuirea matricei de rezultate a obiectului de răspuns la matricea de filme. Singurul lucru pe care trebuie să îl faceți este să ascundeți indicatorul de activitate oprind-o, afișând vizualizarea tabelului și reîncărcând vizualizarea tabelului cu noile date stocate în matricea de filme.

 self.movies = [JSON objectForKey: @ "rezultate"]; [self.activityIndicatorView stopAnimating]; [self.tableView setHidden: NO]; [self.tableView reloadData];

Apoi, modificăm tableView: cellForRowAtIndexPath: metodă. Ajustați implementarea pentru a reflecta cea de mai jos. După obținerea unei referințe la o celulă, vom interoga matricea filmelor pentru elementul corect și vom actualiza etichetele celulei cu titlul și directorul filmului. Construiți și executați aplicația.

 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * cellID = @ "Cell Identifier"; UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: cellID]; dacă (! cell) celula = [[UITableViewCell alocare] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: cellID];  NSDictionary * film = [auto.movies objectAtIndex: indexPath.row]; cell.textLabel.text = [obiect filmForKey: @ "trackName"]; cell.detailTextLabel.text = [film objectForKey: @ "artistName"]; celule retur; 

S-ar putea să fi observat că nu există miniaturi care să fie văzute. Să rezolvăm asta prin adăugarea a trei linii suplimentare către noi tableView: cellForRowAtIndexPath: metodă. Construiți și executați aplicația.

 NSURL * url = [[NSURL alocare] initWithString: [film objectForKey: @ "artworkUrl100"]]; NSData * date = [NSData dataWithContentsOfURL: url]; cell.imageView.image = [[UIImage alocare] initWithData: date];

Ați observat că vizualizarea noastră de tabelă nu derulează fără probleme. De ce este asta? După cum am menționat într-un tutorial anterior, întotdeauna trebuie să vă asigurați că firul principal al aplicației dvs. rămâne receptiv. În punerea în aplicare a noastre tableView: cellForRowAtIndexPath: , descărcăm miniaturile pe firul principal. Aceasta înseamnă că interfața cu utilizatorul nu poate fi actualizată până când nu este terminată o cerere pentru o miniatură. Miniaturile noastre sunt minuscule, astfel încât solicitările nu durează prea mult pentru a fi finalizate, dar imaginați-vă că urmați aceeași abordare pentru activele mai mari. Experiența utilizatorului ar fi teribilă. Chiar și pentru aplicația noastră simplă, experiența utilizatorului este inacceptabilă. Cu toate acestea, putem remedia acest lucru cu o caracteristică foarte utilă a bibliotecii AFNetworking.


AFNetworking la salvare

Creatorii site-ului AFNetworking au văzut nevoia de a descărca active și în fundal. Prin urmare, au creat o categorie pentru UIImageView. Această categorie vă permite să descărcați imagini în fundal cu numai două linii de cod. Această categorie este un adevărat salvator de viață. Priviți fragmentul de mai jos.

 NSURL * url = [[NSURL alocare] initWithString: [film objectForKey: @ "artworkUrl100"]]; [cell.imageView setImageWithURL: url placeholderImage: [UIImage imageNamed: @ "placeholder"]];

Prima linie de cod rămâne aceeași. În al doilea rând, afirmăm imaginea în care miniatura este localizată prin trecerea unui NSURL și treceți într-o imagine de tip placeholder, care este afișată atât timp cât solicitarea noastră nu a returnat un răspuns. Cat de tare e asta? Tot ce trebuie să facem este să adăugăm o imagine cu destinația locului în proiectul nostru. Aceasta poate fi orice imagine doriți, dar puteți găsi imaginea pe care am folosit-o ca substituent în fișierul de descărcare atașat la acest tutorial. Odată ce ați adăugat imaginea substituentului, creați și executați aplicația și testați-vă cât de neted este afișarea tabelului!


Concluzie

Rețineți că aplicația noastră are o bază foarte mare în execuția ei, deoarece nu face nici o cache și putem căuta în iTunes Store doar termenul "harry" în secțiunea de filme. Cu toate acestea, cu un efort foarte mic, puteți face o aplicație elegantă pentru a căuta magazinul iTunes într-un mod mai dinamic.

Sper că acest tutorial v-a convins că biblioteca AFNetworking este un instrument excelent pentru a avea în arsenalul dvs. Poate face mult mai mult decât ceea ce ți-am arătat în acest post, dar scopul principal al acestui tutorial este să te pregătești să lucrezi cu AFNetworking și să îl folosești într-un scenariu real.

Cod