Nei tutorial precedenti, abbiamo esplorato i fondamenti del NSURLSession
API. C'è un'altra caratteristica del NSURLSession
API che non abbiamo ancora esaminato, cioè caricamenti e download fuori processo. Nei prossimi due tutorial, ti mostrerò come creare un client per podcast molto semplice che abiliti i download in background.
Il client podcast che stiamo per creare non sarà davvero funzionale. Permetterà all'utente di interrogare l'API di ricerca di iTunes per un elenco di podcast, selezionare un podcast e scaricare episodi. Dal momento che ci stiamo concentrando sul NSURLSession
API, non andremo a riprodurre gli episodi dei download dell'applicazione.
Il progetto, tuttavia, ti insegnerà come utilizzare le attività di dati e le attività di download in un'applicazione reale. Il client podcast abiliterà anche i download in background per i quali faremo leva NSURLSession
L'API out-of-process. Abbiamo parecchie cose da fare quindi non perdiamo tempo e iniziamo.
Accendi Xcode 5, seleziona Nuovo> Progetto ... dal File menu e scegliere il Applicazione vista singola modello dall'elenco di modelli di applicazioni iOS. Dai un nome all'applicazione singlecast, impostare il Famiglia di dispositivi a i phone, e dire a Xcode dove vorresti salvare il progetto. Colpire Creare per creare il progetto.
La prima cosa che dobbiamo fare è modificare lo storyboard principale del progetto. Aperto Main.storyboard, seleziona l'unico controller di visualizzazione dello storyboard e scegli Incorporare in> Controller di navigazione dal editore menu. Il motivo per l'incorporamento del controller di visualizzazione in un controller di navigazione diventerà chiaro più avanti in questo tutorial.
Come ho detto nell'introduzione, per mantenere le cose semplici, l'utente sarà in grado di iscriversi a un solo podcast. Iniziamo creando il controller della vista di ricerca. Selezionare Nuovo> File ... dal File menu e scegliere Classe Objective-C dalle opzioni a destra. Dai un nome alla classe MTSearchViewController
e renderlo una sottoclasse di UIViewController
. Lasciare la casella di controllo etichettata Con XIB per l'interfaccia utente incontrollato. Dillo a Xcode dove vuoi salvare i file di classe e colpire Creare.
Prima di creare l'interfaccia utente, aprire il file di intestazione del controller della vista e aggiornare l'interfaccia della classe come mostrato di seguito. Specifichiamo che il MTSearchViewController
classe conforme al UITableViewDataSource
, UITableViewDelegate
, e UISearchBarDelegate
protocolli, dichiariamo due punti vendita, barra di ricerca
e tableView
così come un'azione, Annulla
, per chiudere il controller della vista di ricerca.
#importare@interface MTSearchViewController: UIViewController @property (weak, nonatomic) IBOutlet UISearchBar * searchBar; @property (weak, nonatomic) IBOutlet UITableView * tableView; - (IBAction) cancel: (id) mittente; @fine
Rivisitare lo storyboard principale del progetto e trascinare un nuovo controller di visualizzazione dal Libreria di oggetti sulla destra. Seleziona il nuovo controller di visualizzazione, apri il Identity Inspector a destra e impostare la classe del controller di visualizzazione su MTSearchViewController
. Con il nuovo controller di visualizzazione ancora selezionato, apri il editore menu e scegliere Incorporare in> Controller di navigazione. Trascina una vista tabella nella vista del controller della vista e connetti la vista tabella fonte di dati
e delegare
punti vendita con il controller della visualizzazione di ricerca.
Con la vista tabella ancora selezionata, apri il Ispettore degli attributi, e impostare il numero di celle prototipo in 1
. Seleziona la cella prototipo e imposta la sua proprietà di stile a Sottotitolo e il suo identificativo a SearchCell
.
Trascina una barra di ricerca da Libreria di oggetti e aggiungilo alla vista dell'intestazione della vista tabella. Seleziona la barra di ricerca e collegala delegare
presa con il controller di visualizzazione.
Seleziona il controller della vista e collegalo barra di ricerca
e tableView
prese con la barra di ricerca e la vista tabella rispettivamente. Ci sono alcune altre cose che dobbiamo fare prima di aver finito con lo storyboard.
Apri il Libreria di oggetti e trascinare un elemento del pulsante della barra sulla barra di navigazione. Seleziona la voce del pulsante della barra, collegala con Annulla:
azione che abbiamo dichiarato nell'interfaccia del controller della visualizzazione di ricerca e ne cambiamo l'aspetto Identifier nel Ispettore degli attributi a Annulla.
Trascina una voce del pulsante della barra sulla barra di navigazione del controller della vista (non sul controller della visualizzazione della ricerca) e modificala Identifier nel Ispettore degli attributi a Inserisci. Controlla il trascinamento dalla voce del pulsante della barra sul controller di navigazione del controller della ricerca e seleziona modale dal menu che si apre. Questo crea un seguito dal controller della vista al controller di navigazione del controller della ricerca.
Se dovessi controllare il trascinamento dalla voce del pulsante della barra del controller della vista direttamente al controller della vista di ricerca invece del suo controller di navigazione, il controller di navigazione non verrebbe mai istanziato e non vedresti una barra di navigazione nella parte superiore del controller della visualizzazione della ricerca.Prima di implementare il UITableViewDataSource
e UITableViewDelegate
protocolli nel MTSearchViewController
classe, dobbiamo dichiarare una proprietà che memorizza i risultati di ricerca che otterremo dall'API di ricerca di iTunes. Assegna un nome alla proprietà podcast
come mostrato di seguito. Dichiariamo anche una stringa statica che fungerà da identificatore di riutilizzo delle celle. Corrisponde all'identificatore che abbiamo impostato sulla cella del prototipo pochi istanti fa.
#import "MTSearchViewController.h" @interface MTSearchViewController () @property (strong, nonatomic) NSMutableArray * podcast; @fine
static NSString * SearchCell = @ "SearchCell";
L'implementazione di numberOfSectionsInTableView:
è facile come si arriva. Torniamo 1
Se self.podcasts
non è zero
e 0
se è. L'implementazione di tableView: numberOfRowsInSection:
è abbastanza simile come puoi vedere qui sotto. Nel tableView: cellForRowAtIndexPath:
, chiediamo la vista tabella per una cella passando l'identificatore di riutilizzo delle celle, che abbiamo dichiarato in precedenza, e indexPath
. Prendiamo l'oggetto corrispondente dal podcast
fonte di dati e aggiornare la cella di visualizzazione tabella. Tutti e due tableView: canEditRowAtIndexPath:
e tableView: canMoveRowAtIndexPath:
ritorno NO
.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.podcasts? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section return self.podcasts? self.podcasts.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SearchCell forIndexPath: indexPath]; // Fetch Podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Configura cella Visualizza tabella [cell.textLabel setText: [podcast objectForKey: @ "collectionName"]]; [cell.detailTextLabel setText: [podcast objectForKey: @ "artistName"]]; cella di ritorno;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Prima di eseguire l'applicazione, implementare il Annulla:
azione in cui ignoriamo il controller della vista di ricerca.
- (IBAction) cancel: (id) sender [self dismissViewControllerAnimated: YES completion: nil];
Creare il progetto ed eseguire l'applicazione per assicurarsi che la base funzioni come previsto. È ora di iniziare a usare il NSURLSession
API per interrogare l'API di ricerca di iTunes.
Iniziamo dichiarando due proprietà private aggiuntive in MTSearchViewController
classe, sessione
e dataTask
. Il sessione
variabile è usata per memorizzare un riferimento al NSURLSession
istanza che useremo per interrogare l'API di Apple. Manteniamo inoltre un riferimento all'attività dati che useremo per la richiesta. Questo ci consentirà di annullare l'attività di dati se l'utente aggiorna la query di ricerca prima che abbiamo ricevuto una risposta dall'API. Se hai un occhio per i dettagli, potresti aver notato che il MTSearchViewController
la classe è anche conforme al UIScrollViewDelegate
protocollo. La ragione di ciò diventerà chiara in pochi minuti.
#import "MTSearchViewController.h" @interface MTSearchViewController ()@property (strong, nonatomic) NSURLSession * session; @property (strong, nonatomic) NSURLSessionDataTask * dataTask; @property (strong, nonatomic) NSMutableArray * podcast; @fine
La sessione viene creata nel suo metodo getter come puoi vedere di seguito. La sua implementazione non dovrebbe riservare sorprese se hai letto i tutorial precedenti. Escludiamo il metodo getter di sessione
proprietà per caricare pigramente la sessione e limitare l'istanziazione e la configurazione della sessione nel suo metodo getter. Questo rende il codice pulito ed elegante.
- (NSURLSession *) session if (! _Session) // Inizializza la configurazione della sessione NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Configura configurazione sessione [sessionConfiguration setHTTPAdditionalHeaders: @ @ "Accept": @ "application / json"]; // Initialize Session _session = [NSURLSession sessionWithConfiguration: sessionConfiguration]; return _session;
Per rispondere all'input dell'utente nella barra di ricerca, implementiamo SearchBar: textDidChange:
del UISearchBarDelegate
protocollo. L'implementazione è semplice. Se Testo di ricerca
è zero
, il metodo torna presto. Se la lunghezza di Testo di ricerca
è lungo meno di quattro caratteri, abbiamo ripristinato la ricerca invocando resetSearch
. Se la query è di quattro caratteri o più, eseguiamo una ricerca chiamando performSearch
sul controller della vista di ricerca.
- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText se (! searchText) restituisce; if (searchText.length <= 3) [self resetSearch]; else [self performSearch];
Prima di ispezionare performSearch
, diamo una rapida occhiata a resetSearch
. Tutto ciò che facciamo resetSearch
sta pulendo il contenuto di podcast
e ricaricando la vista tabella.
- (void) resetSearch // Aggiorna origine dati [self.podcasts removeAllObjects]; // Aggiorna tabella Visualizza [self.tableView reloadData];
Il sollevamento pesante è fatto in performSearch
. Dopo aver memorizzato l'input dell'utente in una variabile denominata domanda
, controlliamo se dataTask
è impostato. Se è impostato, chiamiamo Annulla
su di esso. Questo è importante in quanto non vogliamo ricevere una risposta da un vecchio richiesta che potrebbe non essere più rilevante per l'utente. Questo è anche il motivo per cui abbiamo una sola attività di dati attivi alla volta. Non vi è alcun vantaggio nell'invio di più richieste all'API.
Successivamente, chiediamo alla sessione una nuova istanza di attività dati facendola passare NSURL
istanza e un gestore di completamento. Ricorda che la sessione è la fabbrica che crea attività. Non dovresti mai creare attività tu stesso. Se otteniamo un compito dati valido dalla sessione, chiamiamo curriculum vitae
su di esso come abbiamo visto nelle precedenti esercitazioni.
La logica all'interno del gestore di completamento è a dir poco interessante. Il errore
l'oggetto è importante per noi per diversi motivi. Non solo ci dirà se qualcosa è andato storto con la richiesta, ma è anche utile per determinare se l'attività di dati è stata annullata. Se otteniamo un oggetto di errore, controlliamo se il suo codice di errore è uguale a -999
. Questo codice di errore indica che l'attività dati è stata annullata. Se otteniamo un altro codice di errore, registriamo l'errore nella console. In un'applicazione reale, è necessario migliorare la gestione degli errori e notificare all'utente quando viene generato un errore.
Se non è stato passato alcun errore al gestore di completamento, creiamo un dizionario dal NSData
istanza che è stata passata al gestore di completamento e ne estrapiamo i risultati. Se abbiamo una serie di risultati con cui lavorare, passiamo a processResults:
. Hai notato che abbiamo invocato processResults:
in un blocco GCD (Grand Central Dispatch)? Perché l'abbiamo fatto? Spero che tu ricordi, perché è un dettaglio molto importante. Non abbiamo alcuna garanzia che il gestore di completamento sia invocato sul thread principale. Poiché dobbiamo aggiornare la vista tabella sul thread principale, dobbiamo assicurarci che processResults:
è chiamato sul thread principale.
- (void) performSearch NSString * query = self.searchBar.text; if (self.dataTask) [self.dataTask cancel]; self.dataTask = [self.session dataTaskWithURL: [self urlForQuery: query] completionHandler: ^ (dati NSData *, risposta NSURLResponse *, errore NSError *) if (errore) if (error.code! = -999) NSLog (@ "% @", errore); else NSDictionary * result = [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil]; Risultati NSArray * = [risultato objectForKey: @ "risultati"]; dispatch_async (dispatch_get_main_queue (), ^ if (results) [self processResults: results];); ]; if (self.dataTask) [self.dataTask resume];
Prima di esaminare l'implementazione di processResults:
, Voglio mostrarti rapidamente cosa succede dentro urlForQuery:
, il metodo di supporto che usiamo performSearch
. Nel urlForQuery:
, sostituiamo qualsiasi spazio con a +
firmare per assicurarsi che l'API di ricerca di iTunes sia felice di ciò che viene inviato. Quindi creiamo un NSURL
istanza con esso e restituirlo.
- (NSURL *) urlForQuery: (NSString *) query query = [query stringByReplacingOccurrencesOfString: @ "" withString: @ "+"]; return [NSURL URLWithString: [NSString stringWithFormat: @ "https://itunes.apple.com/search?media=podcast&entity=podcast&term=%@", query]];
Nel processResults:
, il podcast
la variabile viene cancellata, popolata con il contenuto di risultati
, e i risultati vengono visualizzati nella vista tabella.
- (void) processResults: (NSArray *) results if (! self.podcasts) self.podcasts = [NSMutableArray array]; // Aggiorna origine dati [self.podcasts removeAllObjects]; [self.podcasts addObjectsFromArray: risultati]; // Aggiorna tabella Visualizza [self.tableView reloadData];
Quando l'utente tocca una riga nella vista tabella per selezionare un podcast, tableView: didSelectRowAtIndexPath:
del UITableViewDelegate
il protocollo è invocato. La sua implementazione può sembrare strana all'inizio, quindi lascia che ti spieghi cosa sta succedendo. Selezioniamo il podcast che corrisponde alla selezione dell'utente, lo memorizziamo nel database delle impostazioni predefinite dell'utente dell'applicazione e ignoriamo il controller della vista di ricerca. Non avvisiamo nessuno di questo? Perché lo facciamo diventerà chiaro una volta che continueremo ad implementare il MTViewController
classe.
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath [tableView deselectRowAtIndexPath: indexPath animato: YES]; // Fetch Podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Aggiorna utente Defatuls NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: podcast forKey: @ "MTPodcast"]; [ud synchronize]; // Ignora controller vista [self dismissViewControllerAnimated: YES completion: nil];
Ci sono due dettagli di cui voglio parlare prima di tornare al MTViewController
classe. Quando il controller della vista di ricerca viene presentato all'utente, è chiaro che desidera cercare i podcast. È quindi consigliabile presentare immediatamente la tastiera. Lo facciamo dentro viewDidAppear:
come mostrato di seguito.
- (void) viewDidAppear: (BOOL) animato [super viewDidAppear: animato]; // Mostra tastiera [self.searchBar diventaFirstResponder];
La tastiera deve nascondersi nel momento in cui l'utente inizia a scorrere i risultati della ricerca. Per realizzare ciò, implementiamo scrollViewDidScroll:
del UIScrollViewDelegate
protocollo. Questo spiega perché MTSearchViewController
conforme al UIScrollViewDelegate
protocollo. Dai un'occhiata all'implementazione di scrollViewDidScroll:
mostrato sotto.
- (void) scrollViewDidScroll: (UIScrollView *) scrollView if ([self.searchBar isFirstResponder]) [self.searchBar resignFirstResponder];Il
UITableView
la classe è una sottoclasse di UIScrollView
, quale è la ragione per cui l'approccio sopra funziona. Come abbiamo visto in precedenza, memorizziamo la selezione dell'utente nel database di default dell'utente dell'applicazione. Abbiamo bisogno di aggiornare il MTViewController
classe per utilizzare la selezione dell'utente nel controller della visualizzazione di ricerca. Nel controller della vista viewDidLoad
metodo, carichiamo il podcast dal database di default dell'utente e aggiungiamo il controller di visualizzazione come osservatore del database di default dell'utente per il percorso chiave MTPodcast
in modo che al controller della vista venga notificato il valore per MTPodcast
i cambiamenti.
- (void) viewDidLoad [super viewDidLoad]; // Carica Podcast [auto loadPodcast]; // Aggiungi Observer [[NSUserDefaults standardUserDefaults] addObserver: self forKeyPath: @ Opzioni "MTPodcast": NSKeyValueObservingOptionNew context: NULL];
Tutto ciò che facciamo loadPodcast
sta memorizzando il valore per MTPodcast
dal database di default dell'utente nel controller della vista Podcast
proprietà. Questo valore sarà zero
se il database di default dell'utente non contiene una voce per MTPodcast
. Il controller della vista gestirà con grazia questo per noi. Ricorda che, in Objective-C, puoi inviare messaggi a zero
senza che si scateni l'inferno. Questo ha i suoi svantaggi, ma certamente ha i suoi vantaggi.
- (void) loadPodcast NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; self.podcast = [ud objectForKey: @ "MTPodcast"];
Ciò significa anche che dobbiamo dichiarare una proprietà denominata Podcast
nel file di implementazione del controller della vista.
#import "MTViewController.h" @interface MTViewController () @property (strong, nonatomic) NSDictionary * podcast; @fine
Diamo anche un'occhiata veloce setPodcast:
e updateView
.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Aggiorna Visualizza [auto updateView];
- (void) updateView // Aggiorna View self.title = [self.podcast objectForKey: @ "collectionName"];
Quando il valore nel database predefinito dell'utente cambia per la chiave MTPodcast
, il controller della vista può rispondere a questo cambiamento observeValueForKeyPath: ofObject: cambiamento: contesto:
. Ecco come funziona l'osservazione dei valori chiave. Tutto ciò che facciamo in questo metodo è l'aggiornamento del valore del controller della vista Podcast
proprietà.
- (void) observValueForKeyPath: (NSString *) keyPath ofObject: (id) modifica dell'oggetto: (NSDictionary *) modifica contesto: (void *) context if ([keyPath isEqualToString: @ "MTPodcast"]) self.podcast = [oggetto objectForKey: @ "MTPodcast"];
Quando si lavora con l'osservazione dei valori chiave, è fondamentale essere consapevoli della gestione della memoria e dei cicli di conservazione. In questo caso, significa che è necessario rimuovere il controller di visualizzazione come osservatore quando il controller di visualizzazione è deallocato.
- (void) dealloc [[NSUserDefaults standardUserDefaults] removeObserver: self forKeyPath: @ "MTPodcast"];
La risposta che otteniamo dall'API di ricerca di iTunes include a feedUrl
attributo per ogni podcast. Potremmo recuperare manualmente il feed e analizzarlo. Tuttavia, per risparmiare tempo, utilizzeremo MWFeedParser, una libreria popolare che può farlo per noi. Puoi scaricare e includere manualmente la libreria nel tuo progetto, ma opterò per Cocoapods. Preferisco Cocoapods per la gestione delle dipendenze nei progetti iOS e OS X. Puoi leggere ulteriori informazioni su Cocoapods sul suo sito web o su Mobiletuts+.
Esci da Xcode, vai alla radice del tuo progetto Xcode e crea un file chiamato Podfile. Apri questo file nel tuo editor di testo preferito e aggiungi le seguenti tre righe di codice. Nella prima riga, specifichiamo la piattaforma e l'obiettivo di distribuzione, che è iOS 7 in questo esempio. Le due righe successive specificano ciascuna una dipendenza del nostro progetto Xcode. Il primo è il MWFeedParser biblioteca e ho anche incluso il popolare SVProgressHUD libreria, che tornerà utile un po 'più tardi.
piattaforma: ios, '7' pod 'MWFeedParser' pod 'SVProgressHUD'
Apri una finestra di Terminale, vai alla radice del tuo progetto Xcode ed esegui il comando installazione pod
. Questo dovrebbe installare le dipendenze e creare uno spazio di lavoro Xcode. Quando Cocoapods ha finito di installare le dipendenze del progetto, ti dice di usare lo spazio di lavoro che ha creato per te. Questo è importante quindi non ignorare questo consiglio. Nella radice del tuo progetto Xcode, vedrai che Cocoapods ha davvero creato uno spazio di lavoro Xcode per te. Fai doppio clic su questo file e dovresti essere pronto per partire.
Aprire il file di implementazione di MTViewController
classe, aggiungere una dichiarazione di importazione per MWFeedParser e SVProgressHUD, e dichiarare due proprietà, Episodi
e feedParser
. Dobbiamo anche fare MTViewController
conforme al MWFeedParserDelegate
protocollo.
#import "MTViewController.h" #import "MWFeedParser.h" #import "SVProgressHUD.h" @interface MTViewController ()@property (strong, nonatomic) NSDictionary * podcast; @property (strong, nonatomic) NSMutableArray * episodi; @property (strong, nonatomic) MWFeedParser * feedParser; @fine
Successivamente, aggiorniamo setPodcast:
invocando fetchAndParseFeed
, un metodo di supporto in cui usiamo il MWFeedParser
classe per recuperare e analizzare il feed del podcast.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Aggiorna Visualizza [auto updateView]; // Fetch and Parse Feed [self fetchAndParseFeed];
Nel fetchAndParseFeed
, ci liberiamo della nostra corrente MWFeedParser
istanza se ne abbiamo uno e inizializzare una nuova istanza con l'URL del feed del podcast. Abbiamo impostato il feedParseType
proprietà a ParseTypeFull
e impostare il controller di visualizzazione come delegato del parser del feed. Prima di recuperare il feed, usiamo SVProgressHUD
per mostrare un progresso HUD all'utente.
- (void) fetchAndParseFeed if (! self.podcast) return; NSURL * url = [NSURL URLWithString: [self.podcast objectForKey: @ "feedUrl"]]; se (! url) ritorna; if (self.feedParser) [self.feedParser stopParsing]; [self.feedParser setDelegate: nil]; [self setFeedParser: nil]; // Cancella episodi if (self.episodes) [self setEpisodes: nil]; // Initialize Feed Parser self.feedParser = [[MWFeedParser alloc] initWithFeedURL: url]; // Configure Feed Parser [self.feedParser setFeedParseType: ParseTypeFull]; [self.feedParser setDelegate: self]; // Show Progress HUD [SVProgressHUD showWithMaskType: SVProgressHUDMaskTypeGradient]; // Inizia analisi [self.feedParser parse];
Dobbiamo anche implementare due metodi di MWFeedParserDelegate
protocollo, feedParser: didParseFeedItem:
e feedParserDidFinish:
. Nel feedParser: didParseFeedItem:
, inizializziamo il Episodi
proprietà se necessario e passargli l'articolo del feed che il parser del feed ci fornisce.
- (void) feedParser: (MWFeedParser *) parser didParseFeedItem: (MWFeedItem *) item if (! self.episodes) self.episodes = [NSMutableArray array]; [self.episodes addObject: item];
Nel feedParserDidFinish:
, ignoriamo l'HUD di avanzamento e aggiorniamo la vista tabella. Hai detto vista tabella? Giusto. Abbiamo bisogno di aggiungere una vista tabella e implementare il necessario UITableViewDataSource
metodi di protocollo.
- (void) feedParserDidFinish: (MWFeedParser *) parser // Ignora avanzamento HUD [SVProgressHUD respinto]; // Aggiorna Visualizza [self.tableView reloadData];
Prima di aggiornare l'interfaccia utente, apri MTViewController.h
, dichiarare uno sbocco per la vista tabella, e dire al compilatore il MTViewController
classe conforme al UITableViewDataSource
e UITableViewDelegate
protocolli.
#importare@interface MTViewController: UIViewController @property (weak, nonatomic) IBOutlet UITableView * tableView; @fine
Apri lo storyboard principale ancora una volta e aggiungi una vista tabella alla vista del controller della vista. Collega la vista tabella fonte di dati
e delegare
uscite con il controller di visualizzazione e collegare il controller di visualizzazione tableView
presa con la vista tabella. Seleziona la vista tabella, apri il Ispettore degli attributi, e impostare il numero di celle prototipo in 1
. Seleziona la cella prototipo, imposta il suo stile su Sottotitolo, e dargli un identificativo di EpisodeCell.
Prima di implementare il UITableViewDataSource
protocollo, dichiarare una stringa statica chiamata EpisodeCell
nel MTViewController.m. Ciò corrisponde all'identificatore che abbiamo impostato per la cella del prototipo nello storyboard.
static NSString * EpisodeCell = @ "EpisodeCell";
Implementare il UITableViewDataSource
il protocollo è semplice come una torta e molto simile a come abbiamo implementato il protocollo nel controller della vista di ricerca. L'unica differenza è che il Episodi
variabile contiene istanze di MWFeedItem
classe invece di NSDictionary
casi.
- (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]; // Recupera elemento feed MWFeedItem * feedItem = [self.episodes objectAtIndex: indexPath.row]; // Configura la cella Visualizza tabella [cell.textLabel setText: feedItem.title]; [cell.detailTextLabel setText: [NSString stringWithFormat: @ "% @", feedItem.date]]; cella di ritorno;
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Esegui l'applicazione in iOS Simulator o su un dispositivo fisico ed eseguila attraverso i suoi passi. Ora dovresti essere in grado di cercare i podcast, selezionare un podcast dall'elenco e vedere i suoi episodi.
Abbiamo fatto molto in questo tutorial, ma abbiamo ancora un bel po 'di lavoro davanti a noi. Nel prossimo tutorial, ingrandiremo il download di episodi dal feed e discuteremo di download in background o out-of-process. Rimanete sintonizzati.