I de foregående opplæringsprogrammene har vi utforsket grunnleggende for NSURLSession
API. Det er en annen funksjon av NSURLSession
API som vi ikke har sett på ennå, det vil si opplasting og nedlastinger utenom prosessen. I de neste to opplæringsprogrammene vil jeg vise deg hvordan du lager en veldig enkel podcastklient som muliggjør bakgrunnsnedlastinger.
Podcast-klienten som vi skal skape, vil egentlig ikke være så funksjonell. Det vil tillate brukeren å spørre iTunes Search API for en liste over podcaster, velge en podcast og laste ned episoder. Siden vi fokuserer på NSURLSession
API, vil vi ikke gå inn i å spille episodene programmet lastes ned.
Prosjektet vil imidlertid lære deg hvordan du bruker dataoppgaver og laster ned oppgaver i en ekte verdensapplikasjon. Podcast-klienten vil også aktivere bakgrunnsnedlastinger som vi vil utnytte NSURLSession
's ut-av-prosess API. Vi har ganske mange ting å gjøre, så la oss ikke kaste bort tid og komme i gang.
Slå opp Xcode 5, velg Nytt> Prosjekt ... fra Fil menyen, og velg Enkeltvisningsprogram mal fra listen over iOS-applikasjonsmaler. Navn søknaden Singlecast, sett Enhetsfamilie til iPhone, og fortell Xcode hvor du vil lagre prosjektet. Truffet Skape å skape prosjektet.
Det første vi må gjøre er å redigere prosjektets hovedfortegnelse. Åpen Main.storyboard, velg storyboardets eneste visningskontroller, og velg Integrer inn> Navigasjons kontroller fra Redaktør Meny. Årsaken til å legge inn visningsregulatoren i en navigasjonsstyring vil bli klar senere i denne opplæringen.
Som jeg nevnte i introduksjonen, for å holde ting enkelt, vil brukeren kun kunne abonnere på en podcast. La oss begynne med å opprette søkevisningsregulatoren. Å velge Ny> Fil ... fra Fil menyen og velg Mål-C klasse fra alternativene til høyre. Gi klassen navn MTSearchViewController
og gjør det til en underklasse av UIViewController
. La avkrysningsboksen være merket Med XIB for brukergrensesnitt ukontrollert. Fortell Xcode hvor du vil lagre klassefilene og treffe Skape.
Før vi oppretter brukergrensesnittet, åpner du tittelkontrollens headerfil og oppdaterer klassens grensesnitt som vist nedenfor. Vi spesifiserer at MTSearchViewController
klassen stemmer overens med UITableViewDataSource
, UITableViewDelegate
, og UISearchBarDelegate
protokoller, erklærer vi to utsalgssteder, søkelinje
og Tableview
så vel som en handling, Avbryt
, å avvise søkevisningsregulatoren.
#importere@interface MTSearchViewController: UIViewController @property (svak, ikkeatomisk) IBOutlet UISearchBar * searchBar; @property (svak, ikkeatomisk) IBOutlet UITableView * tableView; - (IBAction) avbryt: (id) avsender; @slutt
Revisér prosjektets hovedfortegnelse og dra en ny visningscontroller fra Objektbibliotek til høyre. Velg den nye visningsregulatoren, åpne Identitetsinspektør til høyre, og sett visningskontrollens klasse til MTSearchViewController
. Med den nye visningskontrollen fortsatt valgt, åpner du Redaktør menyen og velg Integrer inn> Navigasjons kontroller. Dra en tabellvisning til visningskontrollørens visning og koble tabellvisningen datakilde
og delegat
utsalgssteder med søk visning kontrolleren.
Når tabellvisningen fortsatt er valgt, åpner du Attributtsinspektør, og sett antall prototypeceller til 1
. Velg prototypecellen og sett stilegenskapen til Subtitle og dens identifikator til SearchCell
.
Dra en søkefelt fra Objektbibliotek og legg den til i tabellvisningens toppvisning. Velg søkefeltet og koble til det delegat
uttak med visningsregulatoren.
Velg visningsregulatoren og koble den til søkelinje
og Tableview
uttak med henholdsvis søkelinjen og tabellvisningen. Det er noen andre ting vi må gjøre før vi er ferdige med storyboardet.
Åpne Objektbibliotek og dra et bar-knappelement til navigasjonslinjen. Velg barknappelementet, koble det til med Avbryt:
handling vi erklærte i grensesnittet for søkevisningskontrollen, og endre dens Identifier i Attributtsinspektør til Avbryt.
Dra et barknappelement til navigasjonslinjen på visningsregulatoren (ikke søkevisningsregulatoren) og endre dens Identifier i Attributtsinspektør til Legg til. Kontroller dra fra bar-knappelementet til navigasjonskontrollen for søkvisningskontrollen og velg modal fra menyen som dukker opp. Dette skaper en segue fra visningsregulatoren til navigasjonskontrollen i søkevisningskontrollen.
Hvis du skulle kontrollere å dra av visningsregulatorens barknappelement direkte til søkevisningsregulatoren i stedet for navigasjonsstyringen, ville navigasjonskontrollen aldri bli instantiated, og du vil ikke se en navigeringslinje øverst i søkevisningsregulatoren.Før vi implementerer UITableViewDataSource
og UITableViewDelegate
protokoller i MTSearchViewController
klasse, må vi deklarere en eiendom som lagrer søkeresultatene, vi kommer tilbake fra iTunes Search API. Navn på eiendommen podcaster
som vist under. Vi erklærer også en statisk streng som vil fungere som en cellegenbruk-identifikator. Det tilsvarer identifikatoren vi satt på prototypecellen for noen få øyeblikk siden.
#import "MTSearchViewController.h" @interface MTSearchViewController () @property (sterk, ikkeatomisk) NSMutableArray * podcasts; @slutt
statisk NSString * SearchCell = @ "SearchCell";
Gjennomføringen av numberOfSectionsInTableView:
er så enkelt som det blir. Vi returnerer 1
hvis self.podcasts
er ikke nil
og 0
hvis det er. Gjennomføringen av Tableview: numberOfRowsInSection:
er ganske lik som du kan se nedenfor. I Tableview: cellForRowAtIndexPath:
, Vi spør tabellvisningen for en celle ved å sende cellegenbrukeridentifikatoren, som vi erklærte tidligere, og indexPath
. Vi henter det tilsvarende elementet fra podcaster
datakilde og oppdater tabellvisningscellen. Både Tableview: canEditRowAtIndexPath:
og Tableview: canMoveRowAtIndexPath:
komme tilbake NEI
.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.podcasts? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) seksjon return self.podcasts? self.podcasts.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: SearchCell forIndexPath: indexPath]; // Hent podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Konfigurer tabellvisning Cell [cell.textLabel setText: [podcast objectForKey: @ "collectionName"]]; [cell.detailTextLabel setText: [podcast objectForKey: @ "artistName"]]; returcelle;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Før du kjører programmet, implementer du Avbryt:
handling der vi avviser søkevisningsregulatoren.
- (IBAction) avbryt: (id) avsender [self dismissViewControllerAnimated: JA fullføring: null];
Bygg prosjektet og kjør programmet for å sikre at fundamentet virker som forventet. Det er på tide å begynne å bruke NSURLSession
API for å spørre iTunes Search API.
La oss begynne med å erklære ytterligere to private eiendommer i MTSearchViewController
klasse, økt
og dataTask
. De økt
variabel brukes til å lagre en referanse til NSURLSession
eksempel vi bruker for å spørre Apples API. Vi holder også en referanse til dataoppgaven vi vil bruke til forespørselen. Dette vil gjøre det mulig for oss å avbryte dataoppgaven dersom brukeren oppdaterer søket før vi har mottatt et svar fra API-en. Hvis du har øye med detaljer, har du kanskje lagt merke til at MTSearchViewController
klassen overholder også UIScrollViewDelegate
protokoll. Årsaken til dette vil bli klart om noen få minutter.
#import "MTSearchViewController.h" @interface MTSearchViewController ()@property (strong, nonatomic) NSURLSession * økt; @property (strong, nonatomic) NSURLSessionDataTask * dataTask; @property (strong, nonatomic) NSMutableArray * podcasts; @slutt
Økten er opprettet i sin getter-metode som du kan se nedenfor. Implementeringen bør ikke holde noen overraskelser hvis du har lest de tidligere opplæringene. Vi overstyrer gettermetoden til økt
egenskap for å lazily laste økten og begrense øktens instantiation og konfigurasjon i sin getter metode. Dette gir ren og elegant kode.
- (NSURLSession *) økt if (! _Session) // Initialiser Session Configuration NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Konfigurer sesjonskonfigurasjon [sessionConfiguration setHTTPAdditionalHeaders: @ @ "Accept": @ "application / json"]; // Initialiser økt _session = [NSURLSession sessionWithConfiguration: sessionConfiguration]; tilbake _session;
For å svare på brukerens innspill i søkefeltet, implementerer vi searchbar: textDidChange:
av UISearchBarDelegate
protokoll. Gjennomføringen er enkel. Hvis search
er nil
, Metoden vender tilbake tidlig. Hvis lengden på search
er mindre enn fire tegn langt, tilbakestiller vi søket ved å påkalle resetSearch
. Hvis spørringen er fire tegn eller lengre, utfører vi et søk ved å ringe performSearch
på søkevisningsregulatoren.
- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText if (! searchText) returnere; hvis (searchText.length <= 3) [self resetSearch]; else [self performSearch];
Før vi inspiserer performSearch
, la oss ta en rask titt på resetSearch
. Alt vi gjør i resetSearch
er å rydde innholdet i podcaster
og laster opp tabellvisningen.
- (void) resetSearch // Oppdater datakilde [self.podcasts removeAllObjects]; // Oppdater tabellvisning [self.tableView reloadData];
Den tunge løftingen er ferdig i performSearch
. Etter lagring av brukerens inngang i en variabel som heter spørsmål
, vi sjekker om dataTask
er satt. Hvis det er satt, ringer vi Avbryt
på den. Dette er viktig fordi vi ikke vil motta et svar fra en gammel forespørsel som kanskje ikke lenger er relevant for brukeren. Dette er også grunnen til at vi bare har en aktiv datapost på en gang. Det er ingen fordel i å sende flere forespørsler til API.
Deretter spør vi økten om en ny dataoppgaveeksempel ved å sende den en NSURL
eksempel og en ferdigstillingshåndterer. Husk at økten er fabrikken som skaper oppgaver. Du bør aldri lage oppgaver selv. Hvis vi får en gyldig dataoppgave fra økten, ringer vi gjenoppta
på det som vi så i de foregående opplæringene.
Logikken inne i ferdigstillingshåndteringen er interessant å si mildt. De feil
objekt er viktig for oss av flere grunner. Ikke bare vil det fortelle oss om noe gikk galt med forespørselen, men det er også nyttig for å avgjøre om dataoppgaven ble kansellert. Hvis vi får et feilobjekt, kontrollerer vi om feilkoden er lik -999
. Denne feilkoden indikerer at dataoppgaven ble kansellert. Hvis vi får en annen feilkode, logger vi feilen til konsollen. I en ekte applikasjon må du forbedre feilhåndteringen og varsle brukeren når en feil blir kastet.
Hvis ingen feil ble sendt til fullføringsbehandleren, oppretter vi en ordliste fra NSData
eksempel som ble sendt til fullføringshandleren, og vi trekker ut resultatene fra det. Hvis vi har en rekke resultater å jobbe med, sender vi det videre til processResults:
. Har du lagt merke til at vi påkalte processResults:
i en GCD (Grand Central Dispatch) blokk? Hvorfor gjorde vi det? Jeg håper du husker, fordi det er en veldig viktig detalj. Vi har ingen garanti for at ferdigstillingsbehandleren er påkalt på hovedtråden. Siden vi trenger å oppdatere tabellvisningen på hovedtråden, må vi sørge for at processResults:
kaller på hovedtråden.
- (void) performSearch NSString * query = self.searchBar.text; hvis (self.dataTask) [self.dataTask avbryt]; self.dataTask = [self.session dataTaskWithURL: [self urlForQuery: query] completionHandler: ^ (NSData * data, NSURLResponse * respons, NSError * feil) if (error) if (error.code! =999) NSLog (@ "% @", feil); ellers NSDictionary * result = [NSJSONSerialization JSONObjectWithData: dataalternativer: 0 feil: null]; NSArray * results = [result objectForKey: @ "results"]; dispatch_async (dispatch_get_main_queue (), ^ if (resultater) [selvprosessResultater: resultater];); ]; hvis (self.dataTask) [self.dataTask gjenoppta];
Før vi ser på implementeringen av processResults:
, Jeg vil raskt vise deg hva som skjer i urlForQuery:
, hjelperen vi bruker i performSearch
. I urlForQuery:
, Vi erstatter alle mellomrom med a +
logg for å sikre at iTunes Search API er fornøyd med det vi sender det. Vi lager deretter en NSURL
Installer med det og returner det.
- (NSURL *) urlForQuery: (NSString *) spørring query = [spørre strengByReplacingOccurrencesOfString: @ "" withString: @ "+"]; returnere [NSURL URLWithString: [NSString stringWithFormat: @ "https://itunes.apple.com/search?media=podcast&entity=podcast&term=%@", spørring]];
I processResults:
, de podcaster
variabel er slettet, befolket med innholdet i resultater
, og resultatene vises i tabellvisningen.
- (void) processResults: (NSArray *) resultater if (! self.podcasts) self.podcasts = [NSMutableArray array]; // Oppdater datakilde [self.podcasts removeAllObjects]; [self.podcasts addObjectsFromArray: resultater]; // Oppdater tabellvisning [self.tableView reloadData];
Når brukeren tapper en rad i tabellvisningen for å velge en podcast, Tableview: didSelectRowAtIndexPath:
av UITableViewDelegate
protokollen er påkalt. Implementeringen kan virke merkelig i begynnelsen, så la meg forklare hva som skjer. Vi velger podcasten som tilsvarer brukerens valg, lagrer den i programmets brukerstandarddatabase og avviser søkevisningsregulatoren. Vi underretter ikke noen om dette? Hvorfor vi gjør dette, vil bli klart når vi fortsetter å implementere MTViewController
klasse.
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath [tableView deselectRowAtIndexPath: indexPath animert: YES]; // Hent podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Oppdater User Defatuls NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ut setObject: podcast forKey: @ "MTPodcast"]; [synkronisere] // Avvis View Controller [self dismissViewControllerAnimated: JA ferdigstillelse: null];
Det er to detaljer jeg vil snakke om før jeg kommer tilbake til MTViewController
klasse. Når søkevisningsregulatoren presenteres for brukeren, er det klart at hun vil søke etter podcaster. Det er derfor en god ide å umiddelbart presentere tastaturet. Vi gjør dette inn viewDidAppear:
som vist under.
- (void) viewDidAppear: (BOOL) animert [super viewDidAppear: animated]; // Show Keyboard [self.searchBar becomeFirstRespesponder];
Klaviaturet må gjemme øyeblikket brukeren begynner å rulle gjennom søkeresultatene. For å oppnå dette, implementerer vi scrollViewDidScroll:
av UIScrollViewDelegate
protokoll. Dette forklarer hvorfor MTSearchViewController
samsvarer med UIScrollViewDelegate
protokoll. Se på implementeringen av scrollViewDidScroll:
Vist under.
- (void) scrollViewDidScroll: (UIScrollView *) scrollView if ([self.searchBar isFirstResponder]) [self.searchBar resignFirstResponder];De
UITableView
klassen er en underklasse av UIScrollView
, som er grunnen til at ovennevnte tilnærming fungerer. Som vi så tidligere, lagrer vi brukerens valg i programmets brukerstandarddatabase. Vi må oppdatere MTViewController
klassen for å gjøre bruk av brukerens valg i søkevisningsregulatoren. I visningsregulatorens viewDidLoad
Metode, vi laster podcasten fra brukerstandarddatabasen og vi legger til visningsregulatoren som en observatør av brukerens standarddatabase for nøkkelbanen MTPodcast
slik at visningskontrolleren blir varslet når verdien for MTPodcast
Endringer.
- (void) viewDidLoad [super viewDidLoad]; // Last podcast [self loadPodcast]; // Legg til observatør [[NSUserDefaults standardUserDefaults] addObserver: selv forKeyPath: @ "MTPodcast" alternativer: NSKeyValueObservingOptionNew kontekst: NULL];
Alt vi gjør i loadPodcast
lagrer verdien for MTPodcast
fra brukerens standarddatabase i visningsregulatorens podcast
eiendom. Denne verdien vil være nil
hvis brukerens standarddatabase ikke inneholder en oppføring for MTPodcast
. Utsiktskontrollen håndterer dette med glede for oss. Husk at i Mål-C kan du sende meldinger til nil
uten at helvete bryter løs. Dette har sine ulemper, men det har dessuten fordeler med.
- (ugyldig) loadPodcast NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; self.podcast = [ut objectForKey: @ "MTPodcast"];
Dette betyr også at vi må deklarere en eiendom som heter podcast
i visningsregulatorens implementeringsfil.
#import "MTViewController.h" @interface MTViewController () @property (sterk, ikkeatomisk) NSDictionary * podcast; @slutt
La oss også ta en rask titt på setPodcast:
og updateView
.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Oppdater Vis [self updateView];
- (void) updateView // Oppdater Vis self.title = [self.podcast objectForKey: @ "collectionName"];
Når verdien i brukerens standarddatabase endres for nøkkelen MTPodcast
, visningskontrolleren kan svare på denne endringen i observeValueForKeyPath: ofObject: endring: kontekst:
. Det er slik nøkkelverdi observere fungerer. Alt vi gjør i denne metoden er å oppdatere verdien av visningscontrollerens podcast
eiendom.
- (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) objekt endring: (NSDictionary *) endre kontekst: (void *) kontekst if ([keyPath isEqualToString: @ "MTPodcast"]) self.podcast = [objekt objectForKey: @ "MTPodcast"];
Når man arbeider med nøkkelverdi observerer, er det viktig å være oppmerksom på minnestyring og beholde sykluser. I dette tilfellet betyr det at vi må fjerne visningskontrollen som observatør når visningsregulatoren er allokert.
- (void) dealloc [[NSUserDefaults standardUserDefaults] removeObserver: selv forKeyPath: @ "MTPodcast"];
Responsen vi kommer tilbake fra iTunes Search API inneholder en feedurl
attributt for hver podcast. Vi kunne manuelt hente fôret og analysere det. For å spare litt tid bruker vi imidlertid MWFeedParser, et populært bibliotek som kan gjøre dette for oss. Du kan manuelt laste ned og inkludere biblioteket i prosjektet ditt, men jeg skal velge Cocoapods. Jeg foretrekker Cocoapods for å administrere avhengigheter i IOS og OS X-prosjekter. Du kan lese mer om Cocoapods på nettstedet eller på Mobiletuts+.
Avslutt Xcode, naviger til roten til Xcode-prosjektet, og opprett en fil som heter Podfile. Åpne denne filen i valgfri tekstredigerer og legg til følgende tre linjer med kode. I den første linjen spesifiserer vi plattformen og distribusjonsmålet, som er iOS 7 i dette eksemplet. De to neste linjene angir hver avhengighet av vårt Xcode-prosjekt. Den første er MWFeedParser bibliotek og jeg har også inkludert den populære SVProgressHUD bibliotek, som kommer til nytte litt senere.
plattform: ios, '7' pod 'MWFeedParser' pod 'SVProgressHUD'
Åpne et terminalvindu, naviger til roten til Xcode-prosjektet, og kjør kommandoen pod installasjon
. Dette bør installere avhengighetene og opprette et Xcode arbeidsområde. Når Cocoapods er ferdig med å installere prosjektets avhengigheter, forteller det deg å bruke arbeidsområdet det opprettet for deg. Dette er viktig, så ikke ignorere dette rådet. I roten til Xcode-prosjektet ser du at Cocoapods faktisk har opprettet et Xcode-arbeidsområde for deg. Dobbeltklikk denne filen, og du bør være klar til å gå.
Åpne implementeringsfilen til MTViewController
klasse, legg til en importerklæring for MWFeedParser og SVProgressHUD, og erklære to egenskaper, episoder
og feedParser
. Vi må også gjøre MTViewController
i samsvar med MWFeedParserDelegate
protokollen.
#import "MTViewController.h" #import "MWFeedParser.h" #import "SVProgressHUD.h" @interface MTViewController ()@property (sterk, ikkeatomisk) NSDictionary * podcast; @property (strong, nonatomic) NSMutableArray * episoder; @property (strong, nonatomic) MWFeedParser * feedParser; @slutt
Deretter oppdaterer vi setPodcast:
ved å påkalle fetchAndParseFeed
, en hjelpemetode der vi bruker MWFeedParser
klassen for å hente og analysere podcastens feed.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Oppdater Vis [self updateView]; // Hent og tolk feed [self fetchAndParseFeed];
I fetchAndParseFeed
, vi blir kvitt vår nåværende MWFeedParser
eksempel hvis vi har en og initialiser en ny forekomst med podcastens feed-URL. Vi satte feedParseType
eiendom til ParseTypeFull
og sett visningskontrolleren som feedsparserens delegat. Før vi henter feedet, bruker vi SVProgressHUD
for å vise fremdrift HUD til brukeren.
- (void) fetchAndParseFeed if (! self.podcast) tilbake; NSURL * url = [NSURL URLWithString: [self.podcast objectForKey: @ "feedUrl"]]; hvis (! url) returnerer; hvis (self.feedParser) [self.feedParser stopParsing]; [self.feedParser setDelegate: null]; [self setFeedParser: null]; // Klare episoder hvis (self.episodes) [self setEpisodes: null]; // Initialiser Feed Parser self.feedParser = [[MWFeedParser allok] initWithFeedURL: url]; // Konfigurer Feed Parser [self.feedParser setFeedParseType: ParseTypeFull]; [self.feedParser setDelegate: self]; // Vis fremgang HUD [SVProgressHUD showWithMaskType: SVProgressHUDMaskTypeGradient]; // Start Parsing [self.feedParser parse];
Vi må også implementere to metoder for MWFeedParserDelegate
protokollen, feedParser: didParseFeedItem:
og feedParserDidFinish:
. I feedParser: didParseFeedItem:
, vi initialiserer episoder
Egenskap om nødvendig, og send det fôrelementet som fôrparseren hender til oss.
- (void) feedParser: (MWFeedParser *) parser didParseFeedItem: (MWFeedItem *) element if (! self.episodes) self.episodes = [NSMutableArray array]; [self.episodes addObject: item];
I feedParserDidFinish:
, Vi avviser fremdriften HUD og oppdaterer tabellvisningen. Sa du bordvisning? Det er riktig. Vi må legge til en tabellvisning og implementere nødvendige UITableViewDataSource
protokollmetoder.
- (void) feedParserDidFinish: (MWFeedParser *) parser // Dismiss Progress HUD [SVProgressHUD avskedig]; // Oppdater visning [self.tableView reloadData];
Før vi oppdaterer brukergrensesnittet, åpnes MTViewController.h
, erklære et uttak for tabellvisningen, og fortell kompilatoren på MTViewController
klassen stemmer overens med UITableViewDataSource
og UITableViewDelegate
protokoller.
#importere@interface MTViewController: UIViewController @property (svak, ikkeatomisk) IBOutlet UITableView * tableView; @slutt
Åpne hovedfortegnelsen en gang til, og legg til en tabellvisning til visningskontrollørens visning. Koble tabellvisningen datakilde
og delegat
uttak med visningskontrolleren og koble til visningskontrolleren Tableview
uttak med tabellvisning. Velg tabellvisningen, åpne Attributtsinspektør, og sett antall prototypeceller til 1
. Velg prototypecellen, sett stilen til Subtitle, og gi den en identifikator av EpisodeCell.
Før vi implementerer UITableViewDataSource
protokoll, erklære en statisk streng som heter EpisodeCell
i MTViewController.m. Dette tilsvarer identifikatoren vi satt for prototypecellen i storyboardet.
statisk NSString * EpisodeCell = @ "EpisodeCell";
Gjennomføring av UITableViewDataSource
protokollen er enkel som kake og ligner på hvordan vi implementerte protokollen i søkevisningsregulatoren. Den eneste forskjellen er at episoder
variabel inneholder forekomster av MWFeedItem
klasse i stedet for NSDictionary
forekomster.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.episodes? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) seksjon return self.episodes? self.episodes.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: EpisodeCell forIndexPath: indexPath]; // Hent feed element MWFeedItem * feedItem = [self.episodes objectAtIndex: indexPath.row]; // Konfigurer tabellvisningssel [cell.textLabel setText: feedItem.title]; [cell.detailTextLabel setText: [NSString stringWithFormat: @ "% @", feedItem.date]]; returcelle;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Kjør programmet i iOS-simulatoren eller på en fysisk enhet og kjør den gjennom sine skritt. Du bør nå kunne søke etter podcaster, velge en podcast fra listen, og se episodene.
Vi har gjort mye i denne opplæringen, men vi har fortsatt litt arbeid foran oss. I den neste opplæringen zoomer vi inn på nedlasting av episoder fra feedet, og vi diskuterer nedlastinger i bakgrunnen eller utenom prosessen. Følg med.