Netwerken is moeilijk. Er zijn verschillende bewegende delen bij betrokken en veel factoren moeten worden overwogen om het te laten werken. Gelukkig zijn er in de loop van de tijd een aantal open-sourcebibliotheken ontstaan om het netwerken te vergemakkelijken. AFNetworking, gemaakt en onderhouden door de mensen van Gowalla, is zo'n bibliotheek. In deze zelfstudie wordt het AFNetworking-framework geïntroduceerd en wordt ook aangegeven hoe u de iTunes Store-API kunt opvragen!
In deze tutorial zal ik u kennis laten maken met AFNetworking en u een glimp laten zien van wat deze bibliotheek te bieden heeft. Na een paar minuten met deze bibliotheek te hebben doorgebracht, zult u merken dat het ontworpen is met het oog op gebruiksgemak. Het versnelt niet alleen je ontwikkeling, maar het zorgt ook voor veel moeiteloze netwerktaken. We zullen een eenvoudige applicatie bouwen die de iTunes Store bevraagt op films die overeenkomen met de zoekterm "harry". De resultaten van onze zoekopdracht worden weergegeven in een tabelweergave.
De applicatie die we gaan bouwen, bevraagt de iTunes Store Search API. We zoeken met name in de iTunes Store naar films die overeenkomen met de zoekterm "harry". Als onze vraag succesvol is, verwerken we de resultaten en geven deze weer in een tabelweergave. Elke rij vertegenwoordigt een film met een titel, een regisseur en een miniatuur die de filmillustratie toont. Klaar? Laten we beginnen.
Voordat we onze handen vuil maken met AFNetworking, moeten we een basisfundament bouwen. Dit betekent dat we ons project moeten opzetten, een tabelweergave moeten maken en een activiteitsindicatorweergave moeten toevoegen. We zullen de activiteitsindicator laten zien wanneer ons verzoek wordt verwerkt door de iTunes Store. Dit geeft de gebruiker waardevolle extra feedback die vaak over het hoofd wordt gezien.
Maak een nieuw project in Xcode door de. Te selecteren Toepassing enkele weergave sjabloon uit de lijst met sjablonen. Geef je sollicitatie een naam NetworkingIsFun, voer een bedrijfsidentificatie in, stel "iPhone" in voor de apparaatfamilie en schakel "Gebruik storyboards" uit. Je kunt de rest onaangeroerd laten, maar zorg ervoor dat dat zo is Gebruik automatische referentietelling is nagekeken. Vertel Xcode waar je je project wilt opslaan en klik op "Opslaan".
Hoewel Interface Builder geweldig is, bouw ik mijn interfaces vaak programmatisch, en dat is wat we ook zullen doen in deze tutorial. Het stelt ons in staat om ons gewoon op de code te concentreren zonder afgeleid te worden door Interface Builder. Open ViewController.h en maak drie instantievariabelen (ivars) en eigenschappen voor deze ivars. Omdat we met een tabelweergave gaan werken, vergeet niet om uw view controller conform te maken met de UITableViewDataSource en UITableViewDelegate protocols. Het header-bestand van uw view controller moet nu er ongeveer zo uitzien:
#importeren@interface ViewController: UIViewController UITableView * _tableView; UIActivityIndicatorView * _activityIndicatorView; NSArray * _movies; @property (nonatomic, retain) UITableView * tableView; @property (nonatomic, retain) UIActivityIndicatorView * activityIndicatorView; @property (nonatomic, retain) NSArray * -films; @einde
Als u in de war bent door het gebruik van onderstrepingstekens, raad ik u aan hier hier meer over te lezen. Laat de onderstrepingstekens weg als u denkt dat het er lelijk uitziet of u zich ongemakkelijk voelt. Naast de onderstrepingstekens mogen er geen verrassingen zijn. We verklaren onze UITableView en UIActivityIndicatorView evenals een NSArray, die we zullen gebruiken om de resultaten op te slaan die we terug krijgen van onze zoekopdracht. Klaar? Laten we naar het implementatiebestand van onze view controller gaan.
Omdat we drie eigenschappen in ons header-bestand hebben gedeclareerd, moeten we hun accessors samenvoegen ViewController.m. Nogmaals, als de onderstrepingstekens je verwarren, kun je ze weglaten.
@synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView, movies = _movies;
In onze viewDidLoad methode, stellen we onze tabel- en activiteitsindicatorweergaven in. De onderstaande code moet voor het grootste deel voor zichzelf spreken. Als u nog nooit een tabelweergave hebt ingesteld zonder Interface Builder te gebruiken, ziet u mogelijk enkele regels die u niet kent. In plaats van de tabelweergave in Interface Builder te bedraden, zorgen wij ervoor in de viewDidLoad methode. Na het aanroepen van de superklasse ' viewDidLoad methode, we initiëren onze tabelweergave met een frame en een stijl, en we stellen onze view controller in als de gegevensbron en delegeren van onze tabelweergave. Wanneer onze app wordt gestart, verbergen we onze tabelweergave, omdat we niets te tonen hebben zolang onze query geen resultaten oplevert. Voordat we de tabelweergave als een subweergave aan de weergave van onze view-controller toevoegen, hebben we het autoresizing-masker ingesteld. Het autoresiseringsmasker definieert hoe de tabelweergave moet worden aangepast als de bovenliggende weergave - de weergave van de weergavecontroller waaraan we de tabelweergave toevoegen - in grootte verandert. Dit gebeurt bijvoorbeeld wanneer het apparaat wordt geroteerd. Verward? Maak je geen zorgen. Het is niet belangrijk voor deze toepassing.
- (void) viewDidLoad [super viewDidLoad]; // Opstellings tabel Bekijk self.tableView = [[UITableView alloc] initWithFrame: CGRectMake (0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height) style: UITableViewStylePlain]; self.tableView.dataSource = self; self.tableView.delegate = self; self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.tableView.hidden = YES; [self.view addSubview: self.tableView]; // Indicator activiteit instellen Bekijk self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray]; self.activityIndicatorView.hidesWhenStopped = YES; self.activityIndicatorView.center = self.view.center; [self.view addSubview: self.activityIndicatorView]; [self.activityIndicatorView startAnimating]; // Initialisatie van de gegevensbron self.movies = [[NSArray-toewijzing] init];
Het instellen van de activiteitsindicatorweergave is net zo eenvoudig. We initialiseren de weergave van de activiteitsindicator met een vooraf gedefinieerde stijl, stel deze in hidesWhenStopped eigendom aan JA, en plaats deze in het midden van zijn bovenliggende weergave. Nadat we het hebben toegevoegd aan de weergave van de view controller, beginnen we met het animeren van de activiteitsindicator. De activiteitsindicator zal zichzelf automatisch weergeven sinds we die hebben ingesteld hidesWhenStopped eigenschap naar JA.
Aan het einde van onze viewDidLoad methode, initialiseren we de films matrix. We zullen het later gebruiken om de resultaten van onze zoekopdracht op te slaan.
Voor deze zelfstudie implementeren we slechts twee methoden van het tabelweergave-gegevensbronprotocol. Beide methoden zijn verplicht. Dit is de minimale implementatie die vereist is om ons tabeloverzicht operationeel te krijgen. Hoewel we onze view-controller hebben ingesteld als de gedelegeerde van de tabelweergave, gebruiken we geen van de gedelegeerde methoden in onze applicatie. Als u eerder een tabelweergave hebt gebruikt, zult u geen verrassingen vinden in de methode-implementaties die hieronder worden getoond.
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section if (self.movies && self.movies.count) return self.movies.count; else retourneer 0; - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * cellID = @ "Cell Identifier"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellID]; if (! cel) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle heruseIdentifier: cellID]; return cel;
In tableView: numberOfRowsInSection:, we moeten het aantal rijen in elk gedeelte van de tabelweergave retourneren. In ons voorbeeld bevat de tabelweergave slechts één sectie (standaard), waardoor alles een beetje eenvoudiger wordt. Eerst controleren we of onze films variabele is niet nul en we verifiëren dat het items bevat. Als aan beide vereisten is voldaan, retourneren we het aantal items in de filmserie. Als dit niet het geval is, geven we nul terug.
Onze tableView: cellForRowAtIndexPath: methode is ook eenvoudig. We beginnen met het stellen van ons tabeloverzicht of er een cel is die we opnieuw kunnen gebruiken. Als dit niet het geval is, maken we een nieuwe cel met een stijl en hergebruik-ID. We beëindigen onze implementatie door onze cel te retourneren. Dit zal voor nu doen. U kunt nu uw applicatie bouwen en uitvoeren. Als u de stappen correct hebt uitgevoerd, ziet u de activiteitsindicator als een gek ronddraaien en moet de tabelweergave worden verborgen.
Het toevoegen van AFNetworking aan uw project is eenvoudig als taart. Begin met het downloaden van de bibliotheek vanuit GitHub en pak het archief uit. Het archief bevat een map met de naam AFNetworking, welke de bronbestanden bevat die we in ons project moeten opnemen. Sleep deze hele map naar uw Xcode-project en zorg ervoor dat u dit aanvinkt Kopieer items naar de map van de bestemmingsgroep (indien nodig) en voeg ook de bronbestanden toe aan je doelwit.
Nadat u de AFNetworking-bibliotheek aan uw project hebt toegevoegd, moet u uw toepassing bouwen en uitvoeren en toezien hoe alles uit elkaar valt. Wat is er met ons project gebeurd? Waarom krijgen we al deze waarschuwingen en fouten? Toen we ons Xcode-project opstelden, hebben we dit ingeschakeld Automatische referentietelling (ARC). Op het moment van schrijven maakt de AFNetworking-bibliotheek geen gebruik van ARC. Maar maak je geen zorgen, we kunnen deze nette bibliotheek nog steeds met heel weinig moeite gebruiken. Alles wat we moeten doen is de compiler laten weten dat alle bronbestanden van de AFNetworking-bibliotheek geen ARC gebruiken. Dat is het.
Hoe doen we dit? Selecteer uw project in de Project Navigator en selecteer je doelwit. Klik op de Bouw fases tab in de navigatie bovenaan en open de Compileer bronnen lade. In deze tabel ziet u alle bronbestanden die de compilator bij het compileren zal compileren. De linkerkolom toont de namen van de bestanden en de rechterkolom geeft de vlaggen weer die de compiler zou moeten kennen.
U kunt deze vlaggen zien als instructies of berichten voor de compiler. Het enige wat u hoeft te doen is een compilervlag toevoegen aan elk bronbestand van de AFNetworking-bibliotheek. Hiertoe selecteert u een bronbestand in de lijst en dubbelklikt u op de cel in de rechterkolom. Er verschijnt een klein venster waarin u een of meer compilervlaggen kunt toevoegen. In ons geval typ je gewoon -FNO-objc-arc en klik Gedaan. Deze vlag vertelt de compiler dat het bronbestand ARC niet gebruikt. Zorg ervoor dat u deze vlag toevoegt aan alle tien bronbestanden van de AFNetworking-bibliotheek.
AFNetworking is een bibliotheek die veel voor je kan doen, maar vandaag gaan we alleen gebruikmaken van twee handige functies. Voordat we de AFNetworking-klassen kunnen gaan gebruiken, moeten we de volgende importinstructie net onder de eerste importinstructie toevoegen in het implementatiebestand van uw view-controller..
#import "AFNetworking.h"
Deze importverklaring geeft ons toegang tot alle AFNetworking-klassen. Ga terug naar onze view controller's viewDidLoad methode en voeg het volgende fragment toe onmiddellijk na de initialisatie van de films rangschikking.
NSURL * url = [[NSURL-toewijzing] initWithString: @ "http://itunes.apple.com/search?term=harry&country=us&entity=movie"]; NSURLRequest * request = [[NSURLRequest alloc] initWithURL: url]; AFJSONRequestOperation * operation = [AFJSONRequestOperation JSONRequestOperationWithRequest: request success: ^ (Verzoek NSURLRequest *, antwoord NSHTTPURLResponse *, id JSON) NSLog (@ "% @", JSON); failure: ^ (NSURLRequest * request, NSHTTPURLResponse * response, NSError * error, id JSON) NSLog (@ "Request Failed with Error:% @,% @", error, error.userInfo); ]; [operatie start];
Laat me uitleggen wat er aan de hand is. In de eerste regel maken we de NSURL voor ons verzoek. De reeks die we gebruiken bij de initialisatie komt overeen met het formaat dat de iTunes Store Search API verwacht. De syntaxis van de zoek-API is vrij eenvoudig: de term waarnaar we op zoek zijn, is 'harry', we beperken onze zoekopdracht tot de Amerikaanse iTunes Store en we zoeken alleen naar films. Makkelijk, toch?
Vervolgens initialiseren we een NSURLRequest en geven we de NSURL die we zojuist hebben gemaakt door. Daarna begint AFNetworking. AFNetworking bevat een aantal zeer gespecialiseerde lessen die ons werk heel gemakkelijk maken. Degene die we hier gebruiken is AFJSONRequestOperation. Dit is een klasse die is ontworpen om JSON-gegevens op de achtergrond op te halen en te parseren. Zoals de naam aangeeft, is deze klasse een subklasse van NSOperation of, om preciezer te zijn, een van de superklassen van deze klasse erft van NSOperation. Met de klasse kunt u de gevraagde gegevens ophalen en wordt ook het JSON-antwoord geparseerd. Dit betekent dat we niet te maken hebben met onbewerkte JSON. De gegevens die worden geretourneerd, zijn klaar voor gebruik in uw toepassing. AFNetworking maakt gebruik van de ingebouwde JSON-parser op iOS 5 en valt terug op zijn eigen JSON-parser voor oudere iOS-versies.
Het gebruik van AFJSONRequestOperation is eenvoudig omdat het maar één klassenmethode heeft. Deze klassemethode accepteert drie argumenten: (1) een NSURLRequest, (2) een succesblok, uitgevoerd wanneer het verzoek slaagt, en (3) een foutblok, uitgevoerd wanneer het verzoek mislukt. Als blokken nieuw voor je zijn of als je het niet prettig vindt om ze te gebruiken, raad ik aan de tutorial van Collin Ruffenach over blokken en opsommingen in Mobiletuts + te lezen. Het succesblok neemt drie argumenten: (1) ons NSURLRequest, (2) de NSHTTPURLResponse van ons verzoek en (3) een geparseerd JSON-object. Het foutenblok is bijna identiek. Het enige verschil is dat er een extra argument nodig is, een NSError die meer informatie bevat over wat er mis ging in het geval onze aanvraag mislukt.
Voor testdoeleinden loggen we het geparseerde JSON-object om te zien wat de iTunes Store Search API naar ons terugstuurt. Daarnaast registreren we ook de fout in het foutblok in het geval dat ons verzoek mislukt. Voordat we onze applicatie opnieuw kunnen bouwen en uitvoeren, moeten we de operatie starten door te bellen begin op ons operatie-object. Bouw en voer uw applicatie uit en bekijk de uitvoer in de console.
Als alles goed is gegaan, ziet u de resultaten van ons verzoek bij de console. Het geparseerde JSON-object is een woordenboek met twee sleutels: (1) RESULTCOUNT, die het aantal geretourneerde resultaten bevat en (2) de werkelijke uitslagen als een reeks woordenboeken. We hebben niet alleen de reactie op de console geregistreerd om te zien of ons verzoek succesvol was, we kunnen nu de sleutels van elk item in de resultatenarray zien. We hebben deze toetsen nodig om wat informatie weer te geven in onze tabelweergave.
We zijn nu klaar om de resultaten in onze tabelweergave te tonen. Vervang de loginstructie in het succesblok met het onderstaande fragment. We beginnen met het toewijzen van de resultatenarray van het responsobject aan de filmserie. Het enige dat u hoeft te doen, is de activiteitsindicator verbergen door deze te stoppen, de tabelweergave weer te geven en de tabelweergave opnieuw te laden met de nieuwe gegevens die zijn opgeslagen in de filmserie.
self.movies = [JSON-objectForKey: @ "resultaten"]; [self.activityIndicatorView stopAnimating]; [self.tableView setHidden: NO]; [self.tableBekijk reloadData];
Vervolgens passen we de tableView: cellForRowAtIndexPath: methode. Pas uw implementatie aan om die hieronder weer te geven. Nadat we een verwijzing naar een cel hebben verkregen, vragen we de filmserie om het juiste item en werken de labels van de cel bij met de titel en de regisseur van de film. Bouw en run uw applicatie.
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * cellID = @ "Cell Identifier"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellID]; if (! cel) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle heruseIdentifier: cellID]; NSDictionary * movie = [self.movies objectAtIndex: indexPath.row]; cell.textLabel.text = [movie objectForKey: @ "trackName"]; cell.detailTextLabel.text = [movie objectForKey: @ "artistName"]; terugkeer cel;
Je hebt misschien gemerkt dat er geen miniaturen te zien zijn. Laten we dat oplossen door drie extra regels aan onze toe te voegen tableView: cellForRowAtIndexPath: methode. Bouw en run uw applicatie.
NSURL * url = [[NSURL-toewijzing] initWithString: [movie-objectForKey: @ "artworkUrl100"]]; NSData * data = [NSData dataWithContentsOfURL: url]; cell.imageView.image = [[UIImage alloc] initWithData: data];
Is het u opgevallen dat ons tabeloverzicht niet soepel scrollt. Waarom is dat? Zoals ik in een eerdere tutorial al zei, moet je er altijd voor zorgen dat de rode draad van je applicatie nog steeds goed reageert. In de huidige implementatie van onze tableView: cellForRowAtIndexPath: methode, we downloaden de miniaturen op de hoofdthread. Dit betekent dat de gebruikersinterface pas kan worden bijgewerkt als een miniatuurverzoek is voltooid. Onze miniaturen zijn klein, dus het duurt niet lang voordat de verzoeken zijn voltooid, maar stel je voor dat je dezelfde aanpak kiest voor grotere objecten. De gebruikerservaring zou verschrikkelijk zijn. Zelfs voor onze eenvoudige toepassing is de gebruikerservaring onaanvaardbaar. We kunnen dit echter verhelpen met een zeer handige functie van de AFNetworking-bibliotheek.
De makers van AFNetworking zagen ook de noodzaak om assets op de achtergrond te downloaden. Daarom hebben ze een categorie gemaakt voor UIImageView. Met deze categorie kunt u afbeeldingen op de achtergrond downloaden met slechts twee regels code. Deze categorie is een echte spaarder. Bekijk het onderstaande fragment.
NSURL * url = [[NSURL-toewijzing] initWithString: [movie-objectForKey: @ "artworkUrl100"]]; [cell.imageBekijk setImageWithURL: url placeholderImage: [UIImage imageNamed: @ "placeholder"]];
De eerste regel code blijft hetzelfde. In de tweede regel vertellen we de afbeeldingsweergave waar de miniatuur zich bevindt door een NSURL door te geven en geven we een tijdelijke afbeelding door, die wordt weergegeven zolang onze aanvraag geen reactie heeft geretourneerd. Hoe cool is dat? Het enige wat we moeten doen is een tijdelijke afbeelding aan ons project toevoegen. Dit kan elke gewenste afbeelding zijn, maar u kunt de afbeelding die ik heb gebruikt als tijdelijke aanduiding vinden in het downloadbestand dat bij deze zelfstudie is gevoegd. Nadat u de afbeelding van placeholder hebt toegevoegd, uw toepassing hebt gemaakt en uitgevoerd en zelf hebt getest hoe soepel de tabelweergave schuift!
Houd er rekening mee dat onze applicatie erg basaal is in de uitvoering ervan, aangezien er geen caching plaatsvindt en we alleen in de iTunes Store kunnen zoeken naar de term 'harry' in de filmsectie. Echter, met zeer weinig moeite kunt u een nette applicatie maken om de iTunes Store op een meer dynamische manier te doorzoeken.
Ik hoop dat deze tutorial je heeft overtuigd dat de AFNetworking-bibliotheek een geweldig hulpmiddel is om in je arsenaal te hebben. Het kan veel meer dan wat ik je in deze post liet zien, maar het belangrijkste doel van deze tutorial is om je aan de slag te krijgen met AFNetworking en klaar om het te gebruiken in een echt wereldscenario.