In de vorige tutorials hebben we de grondbeginselen van de NSURLSession
API. Er is nog een ander kenmerk van de NSURLSession
API waar we nog niet naar hebben gekeken, dat wil zeggen, out-of-process uploads en downloads. In de volgende twee tutorials zal ik je laten zien hoe je een heel eenvoudige podcast-client maakt die achtergronddownloads mogelijk maakt.
De podcast-client die we gaan maken, wordt niet zo functioneel. Hiermee kan de gebruiker de iTunes Search API doorzoeken op een lijst met podcasts, een podcast selecteren en afleveringen downloaden. Omdat we ons concentreren op de NSURLSession
API, we zullen niet ingaan op het spelen van de afleveringen die de applicatie downloadt.
Het project leert u echter hoe u datataken en downloadtaken moet gebruiken in een toepassing in de echte wereld. De podcast-client zal ook achtergronddownloads mogelijk maken waar we gebruik van zullen maken NSURLSession
'out-of-process API'. We hebben nogal wat dingen te doen dus laten we geen tijd verspillen en aan de slag gaan.
Start Xcode 5 op, selecteer Nieuw> Project ... van de het dossier menu en kies de Toepassing enkele weergave sjabloon uit de lijst met iOS-applicatiesjablonen. Geef de applicatie een naam Singlecast, stel de Apparaatfamilie naar iPhone, en vertel Xcode waar je het project wilt opslaan. Raken creëren om het project te maken.
Het eerste dat we moeten doen, is het belangrijkste storyboard van het project bewerken. Open Main.storyboard, selecteer de enige beeldcontroller van het storyboard en kies Insluiten> Navigatiecontroller van de Editor menu. De reden voor het insluiten van de weergavecontroller in een navigatiecontroller wordt later in deze zelfstudie duidelijk.
Zoals ik in de inleiding al zei, om de dingen eenvoudig te houden, kan de gebruiker zich slechts op één podcast abonneren. Laten we beginnen met het maken van de zoekview-controller. kiezen Nieuw> Bestand ... van de het dossier menu en kies Objectieve C-klasse uit de opties rechts. Geef de klas een naam MTSearchViewController
en maak er een subklasse van UIViewController
. Laat het selectievakje met het label erop staan Met XIB voor gebruikersinterface aangevinkt. Vertel Xcode waar je de lesbestanden wilt opslaan en klik op creëren.
Voordat we de gebruikersinterface maken, opent u het header-bestand van de view-controller en werkt u de interface van de klasse bij, zoals hieronder wordt weergegeven. We specificeren dat de MTSearchViewController
klas voldoet aan de UITableViewDataSource
, UITableViewDelegate
, en UISearchBarDelegate
protocollen verklaren we twee verkooppunten, zoekbalk
en tableView
evenals een actie, annuleren
, om de zoekview-controller te sluiten.
#importeren@interface MTSearchViewController: UIViewController @property (weak, nonatomic) IBOutlet UISearchBar * searchBar; @property (weak, nonatomic) IBOutlet UITableView * tableView; - (IBAction) cancel: (id) afzender; @einde
Bekijk opnieuw het hoofdvernieuwingsbord van het project en sleep een nieuwe weergaveregelaar uit de Objectbibliotheek aan de rechterkant. Selecteer de nieuwe weergavecontroller, open de Identiteitsinspecteur aan de rechterkant en stel de klasse van de view controller in MTSearchViewController
. Met de nieuwe weergavecontroller nog steeds geselecteerd, opent u de Editor menu en kies Insluiten> Navigatiecontroller. Sleep een tabelweergave naar de weergave van de weergavecontroller en verbind de tabelweergave databron
en delegeren
verkooppunten met de zoek view controller.
Met de tabelweergave nog steeds geselecteerd, opent u de Kenmerken Inspector, en stel het aantal prototype cellen in 1
. Selecteer de prototypencel en stel de stijleigenschap ervan in subtitel en de identifier voor SearchCell
.
Sleep een zoekbalk uit de Objectbibliotheek en voeg het toe aan de kopweergave van de tabelweergave. Selecteer de zoekbalk en verbind deze delegeren
stopcontact met de view-controller.
Selecteer de weergavecontroller en sluit deze aan zoekbalk
en tableView
uitgangen met respectievelijk de zoekbalk en de tabelweergave. Er zijn een paar andere dingen die we moeten doen voordat we klaar zijn met het storyboard.
Open de Objectbibliotheek en sleep een item in de balkknop naar de navigatiebalk. Selecteer het item van de balknop, verbind het met de annuleren:
actie die we in de interface van de zoekview-controller hebben gedeclareerd en de actie ervan hebben gewijzigd Identifier in de Kenmerken Inspector naar annuleren.
Versleep een item in de staafknop naar de navigatiebalk van de view controller (niet de zoek view controller) en verander het Identifier in de Kenmerken Inspector naar Toevoegen. Regel het slepen vanaf het item in de staafknop naar de navigatiecontroller van de zoekview-controller en selecteer modaal uit het menu dat verschijnt. Hierdoor wordt een segue gemaakt van de weergavecontroller naar de navigatiecontroller van de zoekview-controller.
Als u het slepen vanaf het item in de staafknoppen van de view-controller rechtstreeks naar de zoekview-controller zou moeten sturen in plaats van naar de navigatiecontroller, zou de navigatie-controller nooit worden geïnstantieerd en zou er geen navigatiebalk boven aan de zoekview-controller verschijnen.Voordat we de UITableViewDataSource
en UITableViewDelegate
protocollen in de MTSearchViewController
klasse, moeten we een property declareren die de zoekresultaten opslaat die we terug zullen krijgen van de iTunes Search API. Geef de eigenschap een naam podcasts
zoals hieronder getoond. We declareren ook een statische tekenreeks die zal dienen als hergebruik-ID voor cellen. Het correspondeert met de identifier die we een paar ogenblikken geleden op de prototype-cel hebben gezet.
#import "MTSearchViewController.h" @interface MTSearchViewController () @property (strong, nonatomic) NSMutableArray * podcasts; @einde
static NSString * SearchCell = @ "SearchCell";
De implementatie van numberOfSectionsInTableView:
is zo eenvoudig als het wordt. We komen terug 1
als self.podcasts
is niet nul
en 0
als het is. De implementatie van tableView: numberOfRowsInSection:
is vrij gelijkaardig zoals je hieronder kunt zien. In tableView: cellForRowAtIndexPath:
, we vragen de tabelweergave voor een cel door de hergebruik-ID van de cel door te geven, die we eerder hebben verklaard, en indexPath
. We halen het overeenkomstige item van de podcasts
gegevensbron en werk de tabelweergavecel bij. Beide tableView: canEditRowAtIndexPath:
en tableView: canMoveRowAtIndexPath:
terugkeer NEE
.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.podcasts? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectie return self.podcasts? self.podcasts.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SearchCell forIndexPath: indexPath]; // Podcast ophalen NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Tabel tabelweergave configureren [cell.textLabel setText: [podcast-objectForKey: @ "collectionName"]]; [cell.detailTextLabel setText: [podcast-objectForKey: @ "artistName"]]; terugkeer cel;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Voordat u de applicatie uitvoert, implementeert u de annuleren:
actie waarbij we de zoekview-controller afwijzen.
- (IBAction) cancel: (id) afzender [self dismissViewControllerAnimated: YES completion: nil];
Bouw het project en voer de applicatie uit om er zeker van te zijn dat de fundering werkt zoals verwacht. Het is tijd om de. Te gebruiken NSURLSession
API om de iTunes Search API te doorzoeken.
Laten we beginnen met het verklaren van twee aanvullende privé-eigenschappen in de MTSearchViewController
klasse, sessie
en dataTask
. De sessie
variabele wordt gebruikt voor het opslaan van een verwijzing naar de NSURLSession
Zo zullen we bijvoorbeeld de Apple API gebruiken. We houden ook een verwijzing naar de gegevenstaak die we zullen gebruiken voor het verzoek. Hierdoor kunnen we de gegevenstaak annuleren als de gebruiker de zoekopdracht bijwerkt voordat we een antwoord van de API hebben ontvangen. Als u oog heeft voor detail, is het u wellicht opgevallen dat het MTSearchViewController
klasse voldoet ook aan de UIScrollViewDelegate
protocol. De reden hiervoor zal binnen enkele minuten duidelijk worden.
#import "MTSearchViewController.h" @interface MTSearchViewController ()@property (strong, nonatomic) NSURLSession * -sessie; @property (strong, nonatomic) NSURLSessionDataTask * dataTask; @property (strong, nonatomic) NSMutableArray * podcasts; @einde
De sessie is gemaakt volgens de methode van de getter, zoals u hieronder kunt zien. De implementatie zou geen verrassingen moeten bevatten als je de vorige tutorials hebt gelezen. We overschrijven de gettermethode van de sessie
eigenschap om de sessie lui te laden en de instantiatie en configuratie van de sessie in de gettermethode te beperken. Dit zorgt voor schone en elegante code.
- (NSURLSession *) sessie if (! _Session) // Initialize Session Configuration NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Sessieconfiguratie configureren [sessionConfiguration setHTTPAdditionalHeaders: @ @ "Accepteren": @ "application / json"]; // Initialize Session _session = [NSURLSession sessionWithConfiguration: sessionConfiguration]; return _session;
Om te reageren op de invoer van de gebruiker in de zoekbalk, implementeren we zoekbalk: textDidChange:
van de UISearchBarDelegate
protocol. De implementatie is eenvoudig. Als zoektekst
is nul
, de methode komt vroeg terug. Als de lengte van zoektekst
is minder dan vier tekens lang, we resetten de zoekopdracht door op te roepen resetSearch
. Als de vraag vier tekens of langer is, voeren we een zoekopdracht uit door te bellen performSearch
op de zoekview-controller.
- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText if (! searchText) return; if (searchText.length <= 3) [self resetSearch]; else [self performSearch];
Voordat we inspecteren performSearch
, laten we even kijken resetSearch
. Alles wat we doen resetSearch
is de inhoud van podcasts
en het opnieuw laden van de tabelweergave.
- (void) resetSearch // Update Data Source [self.podcasts removeAllObjects]; // Update tabelweergave [self.tableBekijk reloadData];
Het zware werk is binnen gedaan performSearch
. Na het opslaan van de invoer van de gebruiker in een variabele met de naam vraag
, we controleren of dataTask
is ingesteld. Als het is ingesteld, bellen we annuleren
ben ermee bezig. Dit is belangrijk omdat we geen reactie van een willen ontvangen oud verzoek dat mogelijk niet langer relevant is voor de gebruiker. Dit is ook de reden waarom we slechts één actieve gegevenstaak tegelijkertijd hebben. Het heeft geen enkel voordeel om meerdere aanvragen naar de API te sturen.
Vervolgens vragen we de sessie om een nieuwe gegevenstaakinstantie door deze door te geven NSURL
instantie en een voltooiingshandler. Onthoud dat de sessie de fabriek is die taken creëert. Je moet nooit zelf taken maken. Als we een geldige gegevenstaak van de sessie krijgen, bellen we hervatten
erop zoals we in de vorige tutorials zagen.
De logica in de voltooiingshandler is op zijn minst interessant. De fout
object is om verschillende redenen belangrijk voor ons. Het geeft niet alleen aan of er iets mis is gegaan met de aanvraag, maar het is ook handig om te bepalen of de gegevenstaak is geannuleerd. Als we een foutobject krijgen, controleren we of de foutcode gelijk is aan -999
. Deze foutcode geeft aan dat de gegevenstaak is geannuleerd. Als we een andere foutcode krijgen, loggen we de fout in op de console. In een echte toepassing moet u de foutafhandeling verbeteren en de gebruiker op de hoogte stellen wanneer er een fout wordt gegenereerd.
Als er geen fout is doorgegeven aan de voltooiingshandler, maken we een woordenboek van de NSData
instantie die is doorgegeven aan de voltooiingsafhandelaar en we extraheren de resultaten ervan. Als we een reeks resultaten hebben om mee te werken, geven we het door aan processResults:
. Heb je gemerkt dat we hebben opgeroepen processResults:
in een GCD-blok (Grand Central Dispatch)? Waarom hebben we dat gedaan? Ik hoop dat je het onthoudt, want het is een heel belangrijk detail. We hebben geen garantie dat de voltooiingsafhandelaar wordt aangeroepen op de hoofdthread. Omdat we de tabelweergave over de hoofdthema moeten bijwerken, moeten we dat zeker doen processResults:
wordt aangeroepen op de hoofdthread.
- (void) performSearch NSString * query = self.searchBar.text; if (self.dataTask) [self.dataTask cancel]; self.dataTask = [self.session dataTaskWithURL: [self urlForQuery: query] completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) if (error) if (error.code! = -999) NSLog (@ "% @", fout); else NSDictionary * result = [NSJSONSerialisatie JSONObjectWithData: data options: 0 error: nil]; NSArray * results = [result objectForKey: @ "results"]; dispatch_async (dispatch_get_main_queue (), ^ if (results) [self processResults: results];); ]; if (self.dataTask) [self.dataTask cv];
Voordat we kijken naar de implementatie van processResults:
, Ik wil je snel laten zien wat er in gebeurt urlForQuery:
, de helpermethode die we gebruiken performSearch
. In urlForQuery:
, we vervangen alle spaties door een +
teken om ervoor te zorgen dat de iTunes Search API tevreden is met wat we hem sturen. We maken vervolgens een NSURL
bijvoorbeeld ermee en retourneer het.
- (NSURL *) urlForQuery: (NSString *) query query = [query stringByReplacingOccurrencesOfString: @ "" withString: @ "+"]; return [NSURL URLWithString: [NSString stringWithFormat: @ "https://itunes.apple.com/search?media=podcast&entity=podcast&term=%@", query]];
In processResults:
, de podcasts
variabele wordt gewist, gevuld met de inhoud van uitslagen
, en de resultaten worden weergegeven in de tabelweergave.
- (void) processResults: (NSArray *) resultaten if (! self.podcasts) self.podcasts = [NSMutableArray array]; // Gegevensbron bijwerken [self.podcasts removeAllObjects]; [self.podcasts addObjectsFromArray: resultaten]; // Update tabelweergave [self.tableBekijk reloadData];
Wanneer de gebruiker op een rij in de tabelweergave tikt om een podcast te selecteren, tableView: didSelectRowAtIndexPath:
van de UITableViewDelegate
protocol wordt aangeroepen. De implementatie ervan lijkt misschien vreemd, dus laat me uitleggen wat er aan de hand is. We selecteren de podcast die overeenkomt met de selectie van de gebruiker, slaan deze op in de database met gebruikersstandaarden van de toepassing en sluiten de zoekview-controller af. We informeren niemand hierover? Waarom we dit doen, zal duidelijk worden zodra we doorgaan met de implementatie van MTViewController
klasse.
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath [tableView deselectRowAtIndexPath: indexPath geanimeerd: YES]; // Podcast ophalen NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Update User Defatuls NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: podcast forKey: @ "MTPodcast"]; [ud synchroniseren]; // Negeer View Controller [self dismissViewControllerGeanimeerd: YES completion: nil];
Er zijn twee details waar ik het over wil hebben voordat ik terugkeer naar de MTViewController
klasse. Wanneer de zoekview-controller aan de gebruiker wordt gepresenteerd, is het duidelijk dat ze naar podcasts wil zoeken. Het is daarom een goed idee om onmiddellijk het toetsenbord te presenteren. We doen dit in viewDidAppear:
zoals hieronder getoond.
- (void) viewDidAppear: (BOOL) geanimeerde [super viewDidAppear: geanimeerd]; // Show Keyboard [self.searchBar becomeFirstResponder];
Het toetsenbord moet worden verborgen op het moment dat de gebruiker begint door de zoekresultaten te bladeren. Om dit te bereiken, implementeren we scrollViewDidScroll:
van de UIScrollViewDelegate
protocol. Dit verklaart waarom MTSearchViewController
voldoet aan de UIScrollViewDelegate
protocol. Kijk eens naar de implementatie van scrollViewDidScroll:
hieronder weergegeven.
- (void) scrollViewDidScroll: (UIScrollView *) scrollView if ([self.searchBar is FirstResponder]) [self.searchBar resignFirstResponder];De
UITableView
class is een subklasse van UIScrollView
, wat de reden is dat de bovenstaande benadering werkt. Zoals we eerder zagen, slaan we de selectie van de gebruiker op in de database met gebruikersstandaarden van de toepassing. We moeten de MTViewController
klasse om gebruik te maken van de selectie van de gebruiker in de zoekview-controller. In de view controller's viewDidLoad
methode laden we de podcast uit de database met gebruikersstandaarden en voegen we de view controller toe als waarnemer van de database met gebruikersstandaarden voor het sleutelpad MTPodcast
zodat de weergavecontroller een melding krijgt wanneer de waarde voor MTPodcast
veranderingen.
- (void) viewDidLoad [super viewDidLoad]; // Podcast laden [self loadPodcast]; // Observer toevoegen [[NSUserDefaults standardUserDefaults] addObserver: self forKeyPath: @ "MTPodcast" -opties: NSKeyValueObservingOptionNew context: NULL];
Alles wat we doen loadPodcast
is de waarde opslaan voor MTPodcast
van de standaard gebruikersdatabase in de view controller's podcast
eigendom. Deze waarde zal zijn nul
als de standaardinstellingen van de database geen invoer bevatten voor MTPodcast
. De view controller zal dit voor ons netjes afhandelen. Onthoud dat u in Objective-C berichten kunt verzenden naar nul
zonder dat de hel losraakt. Dit heeft zijn nadelen, maar het heeft zeker zijn voordelen.
- (void) loadPodcast NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; self.podcast = [ud objectForKey: @ "MTPodcast"];
Dit betekent ook dat we een eigenschap met de naam moeten declareren podcast
in het implementatiebestand van de view-controller.
#import "MTViewController.h" @interface MTViewController () @property (strong, nonatomic) NSDictionary * podcast; @einde
Laten we ook snel kijken setPodcast:
en updateView
.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Updateweergave [self updateView];
- (void) updateView // Update Bekijk self.title = [self.podcast objectForKey: @ "collectionName"];
Wanneer de waarde in de standaardinstellingen van de gebruiker verandert voor de sleutel MTPodcast
, de weergavecontroller kan op deze wijziging reageren observeValueForKeyPath: ofObject: change: context:
. Dat is hoe key value observing werkt. Alles wat we doen in deze methode is het bijwerken van de waarde van de view controller's podcast
eigendom.
- (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) objectwijziging: (NSDictionary *) verander context: (void *) context if ([keyPath isEqualToString: @ "MTPodcast"]) self.podcast = [object objectForKey: @ "MTPodcast"];
Bij het werken met het observeren van sleutelwaarden, is het van belang om op de hoogte te zijn van geheugenbeheer en cycli te behouden. In dit geval betekent dit dat we de weergavecontroller moeten verwijderen als waarnemer wanneer de weergaveregelaar wordt verwijderd.
- (void) dealloc [[NSUserDefaults standardUserDefaults] removeObserver: self forKeyPath: @ "MTPodcast"];
Het antwoord dat we krijgen van de iTunes Search API bevat een feedUrl
kenmerk voor elke podcast. We kunnen de feed handmatig ophalen en analyseren. Om tijd te besparen, zullen we echter gebruikmaken van MWFeedParser, een populaire bibliotheek die dit voor ons kan doen. Je kunt de bibliotheek handmatig downloaden en opnemen in je project, maar ik ga kiezen voor CocoPods. Ik geef de voorkeur aan Cocoapods voor het beheren van afhankelijkheden in iOS- en OS X-projecten. Je kunt meer over Cocoapods lezen op zijn website of op Mobiletuts+.
Sluit Xcode af, ga naar de hoofdmap van uw Xcode-project en maak een bestand met de naam Podfile. Open dit bestand in uw teksteditor naar keuze en voeg de volgende drie regels code toe. In de eerste regel specificeren we het platform en het implementatiedoel, dit is iOS 7 in dit voorbeeld. De volgende twee regels specificeren elk een afhankelijkheid van ons Xcode-project. De eerste is de MWFeedParser bibliotheek en ik heb ook de populaire opgenomen SVProgressHUD bibliotheek, die iets later van pas zal komen.
platform: ios, '7' pod 'MWFeedParser' pod 'SVProgressHUD'
Open een Terminal-venster, navigeer naar de hoofdmap van uw Xcode-project en voer het commando uit pod installeren
. Dit moet de afhankelijkheden installeren en een Xcode-werkruimte maken. Wanneer Cocoapods klaar is met het installeren van de afhankelijkheden van het project, vertelt het u om de werkruimte te gebruiken die het voor u heeft gemaakt. Dit is belangrijk, dus negeer dit advies niet. In de root van je Xcode-project zul je zien dat Cocoapods inderdaad een Xcode-werkruimte voor je heeft gemaakt. Dubbelklik op dit bestand en u zou klaar moeten zijn om te gaan.
Open het implementatiebestand van de MTViewController
class, voeg een importinstructie toe voor MWFeedParser en SVProgressHUD, en verklaar twee eigenschappen, afleveringen
en feedParser
. We moeten ook maken MTViewController
conform zijn aan de MWFeedParserDelegate
protocol.
#import "MTViewController.h" #import "MWFeedParser.h" #import "SVProgressHUD.h" @interface MTViewController ()@property (strong, nonatomic) NSDictionary * podcast; @property (strong, nonatomic) NSMutableArray * afleveringen; @property (strong, nonatomic) MWFeedParser * feedParser; @einde
Vervolgens updaten we setPodcast:
door aan te roepen fetchAndParseFeed
, een helper-methode waarin we de MWFeedParser
klasse om de feed van de podcast op te halen en te parseren.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Updateweergave [self updateView]; // Fetch and Parse Feed [self fetchAndParseFeed];
In fetchAndParseFeed
, we ontdoen ons van onze stroom MWFeedParser
bijvoorbeeld als we er een hebben en een nieuw exemplaar initialiseren met de feed-URL van de podcast. We hebben de feedParseType
eigendom aan ParseTypeFull
en stel de weergavecontroller in als de delegator van de feedparser. Voordat we de feed ophalen, gebruiken we SVProgressHUD
om een voortgang HUD naar de gebruiker te tonen.
- (ongeldig) fetchAndParseFeed if (! self.podcast) retour; NSURL * url = [NSURL URLWithString: [self.podcast-objectForKey: @ "feedUrl"]]; als (! url) terugkeer; if (self.feedParser) [self.feedParser stopParsing]; [self.feedParser setDelegate: nil]; [self setFeedParser: nil]; // Wis afleveringen als (self.episodes) [self setEpisodes: nil]; // Feed Parser initialiseren self.feedParser = [[MWFeedParser alloc] initWithFeedURL: url]; // Feedparser configureren [self.feedParser setFeedParseType: ParseTypeFull]; [self.feedParser setDelegate: self]; // Show Progress HUD [SVProgressHUD showWithMaskType: SVProgressHUDMaskTypeGradient]; // Start Parsing [self.feedParser parseren];
We moeten ook twee methoden van de MWFeedParserDelegate
protocol, feedParser: didParseFeedItem:
en feedParserDidFinish:
. In feedParser: didParseFeedItem:
, we initialiseren de afleveringen
property indien nodig en geef dit door aan het feeditem dat de feedparser aan ons doorgeeft.
- (void) feedParser: (MWFeedParser *) parser didParseFeedItem: (MWFeedItem *) item if (! self.episodes) self.episodes = [NSMutableArray array]; [self.episodes addObject: item];
In feedParserDidFinish:
, we negeren de voortgang HUD en werken de tabelweergave bij. Zei je tafelweergave? Dat is juist. We moeten een tabelweergave toevoegen en het nodige implementeren UITableViewDataSource
protocol methoden.
- (void) feedParserDidFinish: (MWFeedParser *) parser // beëindiging van de voortgang HUD [SVProgressHUD afwijzen]; // Updateweergave [self.tableBekijk reloadDataView];
Voordat we de gebruikersinterface updaten, opent u MTViewController.h
, verklaar een outlet voor het tafelaanzicht en vertel de compiler het MTViewController
klas voldoet aan de UITableViewDataSource
en UITableViewDelegate
protocollen.
#importeren@interface MTViewController: UIViewController @property (weak, nonatomic) IBOutlet UITableView * tableView; @einde
Open het hoofd storyboard nog een keer en voeg een tabelweergave toe aan de weergave van de view controller. Verbind de tabelweergave's databron
en delegeren
uitgangen met de view controller en verbind de view controller's tableView
stopcontact met het tafelaanzicht. Selecteer de tabelweergave, open de Kenmerken Inspector, en stel het aantal prototype cellen in 1
. Selecteer de prototype cel, stel zijn stijl in subtitel, en geef het een ID van EpisodeCell.
Voordat we de UITableViewDataSource
protocol, een statische tekenreeks met de naam EpisodeCell
in MTViewController.m. Dit komt overeen met de ID die we hebben ingesteld voor de cel van het prototype in het storyboard.
static NSString * EpisodeCell = @ "EpisodeCell";
Implementatie van de UITableViewDataSource
protocol is eenvoudig als taart en lijkt erg op hoe we het protocol hebben geïmplementeerd in de zoekview-controller. Het enige verschil is dat de afleveringen
variabele bevat instanties van de MWFeedItem
klasse in plaats van NSDictionary
instanties.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.episodes? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section return self.episodes? self.episodes.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: EpisodeCell forIndexPath: indexPath]; // Feeditem ophalen MWFeedItem * feedItem = [self.episodes objectAtIndex: indexPath.row]; // Tabel tabelweergave configureren [cell.textLabel setText: feedItem.title]; [cell.detailTextLabel setText: [NSString stringWithFormat: @ "% @", feedItem.date]]; terugkeer cel;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Start de applicatie in de iOS Simulator of op een fysiek apparaat en voer het uit. Je zou nu in staat moeten zijn om naar podcasts te zoeken, een podcast uit de lijst te selecteren en de afleveringen ervan te bekijken.
We hebben veel gedaan in deze tutorial, maar we hebben nog steeds behoorlijk wat werk voor de boeg. In de volgende zelfstudie zoomen we in op het downloaden van afleveringen uit de feed en bespreken we achtergrond of niet-actieve downloads. Blijf kijken.