Arbeiten mit NSURLSession Teil 3

In den vorherigen Tutorials haben wir die Grundlagen des NSURLSession API. Es gibt noch eine weitere Funktion der NSURLSession API, die wir noch nicht untersucht haben, dh Out-of-Process-Uploads und -Downloads. In den nächsten beiden Tutorials werde ich Ihnen zeigen, wie Sie einen sehr einfachen Podcast-Client erstellen, der Hintergrund-Downloads ermöglicht.


Einführung

Der Podcast-Client, den wir gerade erstellen, ist nicht so funktional. Damit kann der Benutzer eine Liste der Podcasts in der iTunes Search API abfragen, einen Podcast auswählen und Episoden herunterladen. Da konzentrieren wir uns auf die NSURLSession API, wir werden nicht die Episoden abspielen, die von der Anwendung heruntergeladen werden.

Das Projekt zeigt Ihnen jedoch, wie Sie Datenaufgaben und Downloadaufgaben in einer realen Anwendung verwenden. Der Podcast-Client ermöglicht auch Hintergrund-Downloads, für die wir wirksam sein werden NSURLSessionOut-of-Process-API. Wir haben eine Menge zu tun, also lassen Sie uns keine Zeit verlieren und beginnen Sie.


1. Projekteinrichtung

Starten Sie Xcode 5, wählen Sie Neu> Projekt… von dem Datei Menü und wählen Sie die Einzelansicht-Anwendung Vorlage aus der Liste der iOS-Anwendungsvorlagen. Benennen Sie die Anwendung Singlecast, stellen Sie das ein Gerätefamilie zu iPhone, und teilen Sie Xcode mit, wo Sie das Projekt speichern möchten. Schlagen Erstellen um das Projekt zu erstellen.




2. Aktualisieren Sie das Storyboard

Als erstes müssen wir das Haupt-Storyboard des Projekts bearbeiten. Öffnen Hauptplatine, Wählen Sie den einzigen Ansichts-Controller des Storyboards aus und wählen Sie Einbetten in> Navigationscontroller von dem Editor Speisekarte. Der Grund für das Einbetten des View-Controllers in einen Navigations-Controller wird später in diesem Lernprogramm deutlich.



3. View View Controller suchen

Schritt 1: Erstellen Sie Klassendateien

Wie ich bereits in der Einführung erwähnt habe, kann der Benutzer zur Vereinfachung nur einen Podcast abonnieren. Beginnen wir mit dem Erstellen des Suchansicht-Controllers. Wählen Neu> Datei… von dem Datei Menü und wählen Sie Ziel-C-Klasse aus den Optionen rechts. Benennen Sie die Klasse MTSearchViewController und mache es eine Unterklasse von UIViewController. Lassen Sie das Kontrollkästchen beschriftet Mit XIB für die Benutzeroberfläche ungeprüft Sagen Sie Xcode, wo Sie die Klassendateien speichern möchten, und klicken Sie auf Erstellen.


Schritt 2: Klassenschnittstelle aktualisieren

Bevor Sie die Benutzeroberfläche erstellen, öffnen Sie die Header-Datei des View-Controllers und aktualisieren Sie die Klassenschnittstelle wie unten gezeigt. Wir geben an, dass die MTSearchViewController Klasse entspricht der UITableViewDataSource, UITableViewDelegate, und UISearchBarDelegate Protokolle deklarieren wir zwei Ausgänge, Suchleiste und Tabellenansicht sowie eine Aktion, stornieren, um den Controller für die Suchansicht zu schließen.

 #einführen  @Interface MTSearchViewController: UIViewController  @ property (schwach, nichtatomisch) IBOutlet UISearchBar * searchBar; @ property (schwach, nicht atomar) IBOutlet UITableView * tableView; - (IBAction) cancel: (ID) Absender; @Ende

Schritt 3: Benutzeroberfläche erstellen

Sehen Sie sich das Haupt-Storyboard des Projekts erneut an und ziehen Sie einen neuen Ansichts-Controller aus dem Ordner Objektbibliothek zur Rechten. Wählen Sie den neuen View-Controller aus, öffnen Sie die Identitätsinspektor auf der rechten Seite und setzen Sie die Klasse des View-Controllers auf MTSearchViewController. Öffnen Sie bei noch ausgewähltem neuen Ansichts-Controller die Editor Menü und wählen Sie Einbetten in> Navigationscontroller. Ziehen Sie eine Tabellenansicht in die Ansicht des Ansichtscontrollers und verbinden Sie die Tabellenansicht Datenquelle und delegieren Steckdosen mit der Suchansicht-Controller.


Öffnen Sie bei ausgewählter Tabellenansicht die Attribute-Inspektor, und stellen Sie die Anzahl der Prototypzellen auf 1. Wählen Sie die Prototypzelle aus, und legen Sie ihre Stileigenschaft auf fest Untertitel und seine Kennung zu SearchCell.


Ziehen Sie eine Suchleiste aus der Objektbibliothek und fügen Sie es der Kopfansicht der Tabellenansicht hinzu. Wählen Sie die Suchleiste aus und verbinden Sie sie delegieren Steckdose mit dem View Controller.


Wählen Sie den View Controller aus und verbinden Sie ihn Suchleiste und Tabellenansicht Verkaufsstellen mit der Suchleiste bzw. der Tabellenansicht. Es gibt ein paar andere Dinge, die wir tun müssen, bevor wir mit dem Storyboard fertig sind.

Öffne das Objektbibliothek Ziehen Sie ein Bar-Schaltflächenelement in die Navigationsleiste. Wählen Sie den Bar-Button aus und verbinden Sie ihn mit dem stornieren: Aktion, die wir in der Schnittstelle des Suchansicht-Controllers deklariert haben, und deren Änderung ändern Kennung in dem Attribute-Inspektor zu Stornieren.


Ziehen Sie ein Bar-Schaltflächenelement in die Navigationsleiste des View-Controllers (nicht den Such-View-Controller), und ändern Sie dessen Element Kennung in dem Attribute-Inspektor zu Hinzufügen. Ziehen Sie das Element von der Schaltflächenschaltfläche zum Navigationscontroller des Suchansicht-Controllers, und wählen Sie modal aus dem Menü, das erscheint. Dadurch wird ein Segue vom View Controller zum Navigationscontroller des Search View Controllers erstellt.

Wenn Sie das Ziehen vom Bar-Schaltflächenelement des View-Controllers direkt zum Such-View-Controller anstelle des Navigationscontrollers steuern würden, würde der Navigationscontroller niemals instanziiert und es würde keine Navigationsleiste oben im Suchansicht-Controller angezeigt.

Schritt 4: Implementierung der Tabellensicht

Bevor wir das implementieren UITableViewDataSource und UITableViewDelegate Protokolle in der MTSearchViewController In dieser Klasse müssen wir eine Eigenschaft angeben, in der die Suchergebnisse gespeichert werden, die wir von der iTunes-Such-API erhalten. Benennen Sie die Eigenschaft Podcasts Wie nachfolgend dargestellt. Wir deklarieren auch eine statische Zeichenfolge, die als Bezeichner für die Wiederverwendung von Zellen dient. Sie entspricht der Kennung, die wir vor wenigen Augenblicken in der Prototypzelle festgelegt haben.

 #import "MTSearchViewController.h" @interface MTSearchViewController () @property (stark, nicht atomar) NSMutableArray * -Podcasts; @Ende
 statischer NSString * SearchCell = @ "SearchCell";

Die Implementierung von numberOfSectionsInTableView: ist so einfach wie es nur geht. Wir kehren zurück 1 ob selbst.podcasts ist nicht Null und 0 wenn es so ist Die Implementierung von tableView: numberOfRowsInSection: ist ziemlich ähnlich, wie Sie unten sehen können. Im tableView: cellForRowAtIndexPath:, Wir fragen die Tabellensicht nach einer Zelle, indem wir die zuvor deklarierte Zellwiederverwendungskennung übergeben indexPath. Wir holen den entsprechenden Artikel aus der Podcasts Datenquelle und aktualisieren Sie die Tabellensichtzelle. Beide tableView: canEditRowAtIndexPath: und tableView: canMoveRowAtIndexPath: Rückkehr NEIN.

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.podcasts? 1: 0; 
 - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) Abschnitt return self.podcasts? self.podcasts.count: 0; 
 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SearchCell fürIndexPath: indexPath]; // Podcast abrufen NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Table View Cell konfigurieren [cell.textLabel setText: [Podcast objectForKey: @ "collectionName"]]; [cell.detailTextLabel setText: [Podcast objectForKey: @ "artistName"]]; zurück Zelle; 
 - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO; 
 - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO; 

Bevor Sie die Anwendung ausführen, implementieren Sie das stornieren: Aktion, bei der wir den Suchansicht-Controller abweisen.

 - (IBAction) cancel: (id) sender [self dismissViewControllerAnimated: YES Vervollständigung: nil]; 

Erstellen Sie das Projekt und führen Sie die Anwendung aus, um sicherzustellen, dass die Basis wie erwartet funktioniert. Es ist an der Zeit, mit der NSURLSession API zum Abfragen der iTunes-Such-API.

Schritt 5: Sitzung erstellen

Beginnen wir mit der Deklaration von zwei weiteren privaten Eigenschaften in der MTSearchViewController Klasse, Session und dataTask. Das Session Variable wird verwendet, um einen Verweis auf die zu speichern NSURLSession Beispiel für die Abfrage der API von Apple. Wir führen auch einen Hinweis auf die Datenaufgabe, die wir für die Anfrage verwenden werden. Dies ermöglicht es uns, die Datentask abzubrechen, wenn der Benutzer die Suchabfrage aktualisiert, bevor wir eine Antwort von der API erhalten haben. Wenn Sie ein Auge für Details haben, haben Sie vielleicht bemerkt, dass das MTSearchViewController Klasse entspricht auch der UIScrollViewDelegate Protokoll. Der Grund dafür wird in wenigen Minuten klar.

 #import "MTSearchViewController.h" @interface MTSearchViewController ()  @ property (strong, nonatomic) NSURLSession * Sitzung; @ property (strong, nonatomic) NSURLSessionDataTask * dataTask; @ property (strong, nonatomic) NSMutableArray * -Podcasts; @Ende

Die Sitzung wird in ihrer Getter-Methode erstellt, wie Sie unten sehen können. Die Implementierung sollte keine Überraschungen enthalten, wenn Sie die vorherigen Tutorials gelesen haben. Wir überschreiben die Getter-Methode von Session Mit dieser Eigenschaft können Sie die Sitzung träge laden und die Instantiierung und Konfiguration der Sitzung in ihre Getter-Methode einschränken. Dies sorgt für einen sauberen und eleganten Code.

 - (NSURLSession *) session if (! _Session) // Session-Konfiguration initialisieren NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Sitzungskonfiguration konfigurieren [sessionConfiguration setHTTPAdditionalHeaders: @ @ "Accept": @ "application / json"]; // Sitzung initialisieren _session = [NSURLSession sessionWithConfiguration: sessionConfiguration];  return _session; 

Schritt 6: Suchen

Um auf die Eingaben des Benutzers in der Suchleiste zu reagieren, implementieren wir searchBar: textDidChange: des UISearchBarDelegate Protokoll. Die Implementierung ist einfach. Ob Suchtext ist Null, Die Methode kehrt früh zurück. Wenn die Länge von Suchtext ist weniger als vier Zeichen lang, setzen wir die Suche durch Aufrufen zurück resetSearch. Wenn die Abfrage vier Zeichen oder länger umfasst, führen wir eine Suche durch Aufrufen durch performSearch auf dem Controller für die Suchansicht.

 - (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText if (! searchText) return; if (searchText.length <= 3)  [self resetSearch];  else  [self performSearch];  

Bevor wir inspizieren performSearch, Lassen Sie uns einen kurzen Blick darauf werfen resetSearch. Alles, was wir tun resetSearch löscht den Inhalt von Podcasts und die Tabellenansicht neu laden.

 - (void) resetSearch // Datenquelle aktualisieren [self.podcasts removeAllObjects]; // Table View aktualisieren [self.tableView reloadData]; 

Das schwere Heben erfolgt in performSearch. Nach dem Speichern der Benutzereingabe in einer Variablen namens Abfrage, wir prüfen ob dataTask eingestellt ist. Wenn es eingestellt ist, rufen wir an stornieren darauf Dies ist wichtig, da wir keine Antwort von einem erhalten möchten alt Anforderung, die für den Benutzer möglicherweise nicht mehr relevant ist. Dies ist auch der Grund, warum wir immer nur eine aktive Datenaufgabe haben. Das Senden mehrerer Anforderungen an die API bietet keinen Vorteil.

Als Nächstes fragen wir die Sitzung nach einer neuen Datentask-Instanz, indem wir sie übergeben NSURL Instanz und einen Abschluss-Handler. Denken Sie daran, dass die Sitzung die Factory ist, die Aufgaben erstellt. Sie sollten niemals selbst Aufgaben erstellen. Wenn wir eine gültige Datenaufgabe von der Sitzung erhalten, rufen wir auf fortsetzen darauf, wie wir in den vorherigen Tutorials gesehen haben.

Die Logik im Completion-Handler ist gelinde gesagt interessant. Das Error Das Objekt ist aus mehreren Gründen wichtig für uns. Es zeigt uns nicht nur, ob bei der Anfrage ein Fehler aufgetreten ist, es ist auch hilfreich, um festzustellen, ob die Datenaufgabe abgebrochen wurde. Wenn wir ein Fehlerobjekt erhalten, prüfen wir, ob der Fehlercode gleich ist -999. Dieser Fehlercode zeigt an, dass der Datentask abgebrochen wurde. Wenn wir einen anderen Fehlercode erhalten, protokollieren wir den Fehler in der Konsole. In einer realen Anwendung müssen Sie die Fehlerbehandlung verbessern und den Benutzer benachrichtigen, wenn ein Fehler auftritt.

Wenn kein Fehler an den Completion-Handler übergeben wurde, erstellen wir ein Wörterbuch aus der Datenbank NSData Instanz, die an den Completion-Handler übergeben wurde, und wir extrahieren die Ergebnisse daraus. Wenn wir eine Reihe von Ergebnissen haben, mit denen wir arbeiten können, übergeben wir sie an processResults:. Haben Sie bemerkt, dass wir angerufen haben? processResults: in einem GCD-Block (Grand Central Dispatch)? Warum haben wir das gemacht? Ich hoffe, Sie erinnern sich, weil es ein sehr wichtiges Detail ist. Wir können nicht garantieren, dass der Completion-Handler im Haupt-Thread aufgerufen wird. Da wir die Tabellensicht im Haupt-Thread aktualisieren müssen, müssen wir dies sicherstellen processResults: wird im Hauptthread aufgerufen.

 - (void) performSearch NSString * query = self.searchBar.text; if (self.dataTask) [self.dataTask cancel];  self.dataTask = [self.session dataTaskWithURL: [self urlForQuery: query] completionHandler: ^ (NSData * -Daten, NSURLResponse * -Antwort, NSError * -Fehler) if (error) if (error.code! = -999)  NSLog (@ "% @", Fehler);  else NSDictionary * result = [NSJSONSerialization JSONObjectWithData: Datenoptionen: 0 Fehler: Null]; NSArray * results = [result objectForKey: @ "results"]; dispatch_async (dispatch_get_main_queue (), ^ if (results) [self processResults: results];); ]; if (self.dataTask) [self.dataTask Lebenslauf]; 

Bevor wir uns die Implementierung von ansehen processResults:, Ich möchte Ihnen schnell zeigen, was passiert urlForQuery:, die Hilfsmethode, die wir in verwenden performSearch. Im urlForQuery:, Leerzeichen ersetzen wir mit einem + Melden Sie sich an, um sicherzustellen, dass die iTunes-Such-API mit dem, was wir senden, zufrieden ist. Wir erstellen dann eine NSURL Beispiel mit und geben Sie es zurück.

 - (NSURL *) urlForQuery: (NSString *) Abfrage Abfrage = [Abfrage StringByReplacingOccurrencesOfString: @ "" withString: @ "+"]; return [NSURL URLWithString: [NSString stringWithFormat: @ "https://itunes.apple.com/search?media=podcast&entity=podcast&term=%@", query]]; 

Im processResults:, das Podcasts Die Variable wird gelöscht und mit dem Inhalt von gefüllt Ergebnisse, und die Ergebnisse werden in der Tabellenansicht angezeigt.

 - (void) processResults: (NSArray *) Ergebnisse if (! self.podcasts) self.podcasts = [NSMutableArray-Array];  // Datenquelle aktualisieren [self.podcasts removeAllObjects]; [self.podcasts addObjectsFromArray: Ergebnisse]; // Table View aktualisieren [self.tableView reloadData]; 

Schritt 6: Auswählen eines Podcasts

Wenn der Benutzer in der Tabellenansicht auf eine Zeile tippt, um einen Podcast auszuwählen, tableView: didSelectRowAtIndexPath: des UITableViewDelegate Protokoll wird aufgerufen. Die Implementierung mag auf den ersten Blick merkwürdig erscheinen, also lassen Sie mich erklären, was los ist. Wir wählen den Podcast aus, der der Auswahl des Benutzers entspricht, speichern ihn in der Benutzerstandarddatenbank der Anwendung und schließen den Suchansicht-Controller. Wir benachrichtigen niemanden darüber. Warum wir das tun, wird klar, wenn wir die Implementierung fortsetzen MTViewController Klasse.

 - (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath [tableView deselectRowAtIndexPath: indexPath animated: YES]; // Podcast abrufen NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Benutzerdaten aktualisieren NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: Podcast forKey: @ "MTPodcast"]; [ud synchronisieren]; // View Controller abmelden [self dismissViewControllerAnimated: YES completion: nil]; 

Schritt 7: Fertigstellen von Berührungen

Es gibt zwei Details, über die ich sprechen möchte, bevor ich wieder in die MTViewController Klasse. Wenn der Suchansicht-Controller dem Benutzer angezeigt wird, ist es klar, dass er nach Podcasts suchen möchte. Es ist daher eine gute Idee, die Tastatur sofort zu präsentieren. Wir machen das in viewDidAppear: Wie nachfolgend dargestellt.

 - (void) viewDidAppear: (BOOL) animiert [super viewDidAppear: animiert]; // Tastatur anzeigen [self.searchBar becomeFirstResponder]; 

Die Tastatur muss in dem Moment ausgeblendet werden, in dem der Benutzer durch die Suchergebnisse blättert. Um dies zu erreichen, implementieren wir scrollViewDidScroll: des UIScrollViewDelegate Protokoll. Das erklärt warum MTSearchViewController entspricht der UIScrollViewDelegate Protokoll. Schauen Sie sich die Implementierung von an scrollViewDidScroll: unten gezeigt.

 - (void) scrollViewDidScroll: (UIScrollView *) scrollView if ([self.searchBar isFirstResponder]) [self.searchBar resignFirstResponder]; 
Das UITableView Klasse ist eine Unterklasse von UIScrollView, Aus diesem Grund funktioniert der obige Ansatz.

4. Zurücklaufen

Wie wir bereits gesehen haben, speichern wir die Auswahl des Benutzers in der Benutzer-Standarddatenbank der Anwendung. Wir müssen das aktualisieren MTViewController Klasse, um die Auswahl des Benutzers im Suchansicht-Controller zu verwenden. In der Ansicht Controller viewDidLoad Wir laden den Podcast aus der Datenbank der Benutzervorgaben und fügen den View Controller als Beobachter der Benutzervorgabedatenbank für den Schlüsselpfad hinzu MTPodcast so dass der View Controller benachrichtigt wird, wenn der Wert für MTPodcast Änderungen.

 - (void) viewDidLoad [super viewDidLoad]; // Podcast laden [self loadPodcast]; // Observer hinzufügen [[NSUserDefaults standardUserDefaults] addObserver: self forKeyPath: @ "MTPodcast" -Optionen: NSKeyValueObservingOptionNew context: NULL]; 

Alles was wir tun in loadPodcast speichert den Wert für MTPodcast aus der Benutzer-Standarddatenbank im View-Controller Podcast Eigentum. Dieser Wert wird sein Null wenn die Benutzervorgabendatenbank keinen Eintrag für enthält MTPodcast. Der View-Controller wird dies für uns zügig erledigen. Denken Sie daran, dass Sie in Objective-C Nachrichten senden können Null ohne dass die Hölle losgeht. Das hat seine Nachteile, aber es hat durchaus Vorteile.

 - (void) loadPodcast NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; self.podcast = [ud objectForKey: @ "MTPodcast"]; 

Dies bedeutet auch, dass wir eine Eigenschaft mit dem Namen angeben müssen Podcast in der Implementierungsdatei des View-Controllers.

 #import "MTViewController.h" @interface MTViewController () @property (stark, nicht atomar) NSDictionary * podcast; @Ende

Lassen Sie uns auch einen kurzen Blick darauf werfen setPodcast: und updateView.

 - (void) setPodcast: (NSDictionary *) Podcast if (_podcast! = Podcast) _podcast = Podcast; // Ansicht aktualisieren [self updateView]; 
 - (void) updateView // Aktualisierungsansicht self.title = [self.podcast objectForKey: @ "collectionName"]; 

Wenn der Wert in der Standarddatenbank des Benutzers für den Schlüssel geändert wird MTPodcast, Der View Controller kann auf diese Änderung in reagieren observValueForKeyPath: ofObject: change: context:. So funktioniert das Beobachten von Schlüsselwerten. Bei dieser Methode müssen wir nur den Wert des View-Controllers aktualisieren Podcast Eigentum.

 - (void) observValueForKeyPath: (NSString *) keyPath ofObject: (id) Objektänderung: (NSDictionary *) Kontext ändern: (void *) Kontext if ([keyPath isEqualToString: @ "MTPodcast"]) self.podcast =] object objectForKey: @ "MTPodcast"]; 

Beim Arbeiten mit Schlüsselwerten ist es wichtig, die Speicherverwaltung zu kennen und Zyklen einzuhalten. In diesem Fall bedeutet dies, dass wir den View Controller als Beobachter entfernen müssen, wenn der View Controller freigegeben wird.

 - (void) dealloc [[NSUserDefaults standardUserDefaults] removeObserver: self forKeyPath: @ "MTPodcast"]; 

5. Feed abrufen und analysieren

Schritt 1: Abhängigkeiten hinzufügen

Die Antwort, die wir von der iTunes Search API erhalten, enthält a Feed-URL Attribut für jeden Podcast. Wir könnten den Feed manuell abrufen und analysieren. Um Zeit zu sparen, verwenden wir jedoch MWFeedParser, eine beliebte Bibliothek, die dies für uns tun kann. Sie können die Bibliothek manuell herunterladen und in Ihr Projekt aufnehmen, aber ich werde mich für Cocoapods entscheiden. Ich bevorzuge Cocoapods, um Abhängigkeiten in iOS- und OS X-Projekten zu verwalten. Mehr über Cocoapods erfahren Sie auf der Website oder auf Mobiletuts+.

Ich gehe davon aus, dass der Cocoapods-Edelstein auf Ihrem System installiert ist. Detaillierte Anweisungen finden Sie in diesem Tutorial.

Beenden Sie Xcode, navigieren Sie zum Stammverzeichnis Ihres Xcode-Projekts und erstellen Sie eine Datei mit dem Namen Poddatei. Öffnen Sie diese Datei in Ihrem Texteditor Ihrer Wahl und fügen Sie die folgenden drei Codezeilen hinzu. In der ersten Zeile geben wir die Plattform und das Implementierungsziel an, in diesem Beispiel iOS 7. Die nächsten zwei Zeilen geben jeweils eine Abhängigkeit von unserem Xcode-Projekt an. Der erste ist der MWFeedParser Bibliothek und ich habe auch die beliebte aufgenommen SVProgressHUD Bibliothek, die später etwas nützlich sein wird.

 Plattform: ios, '7' Pod 'MWFeedParser' Pod 'SVProgressHUD'

Öffnen Sie ein Terminalfenster, navigieren Sie zum Stammverzeichnis Ihres Xcode-Projekts und führen Sie den Befehl aus pod installieren. Dies sollte die Abhängigkeiten installieren und einen Xcode-Arbeitsbereich erstellen. Wenn Cocoapods mit der Installation der Abhängigkeiten des Projekts fertig ist, werden Sie aufgefordert, den für Sie erstellten Arbeitsbereich zu verwenden. Dies ist wichtig, ignorieren Sie diesen Ratschlag nicht. Im Stammverzeichnis Ihres Xcode-Projekts sehen Sie, dass Cocoapods tatsächlich einen Xcode-Arbeitsbereich für Sie erstellt hat. Doppelklicken Sie auf diese Datei, und Sie sollten bereit sein.


Schritt 2: Holen und Analysieren des Feeds

Öffnen Sie die Implementierungsdatei von MTViewController Klasse, fügen Sie eine Importanweisung für hinzu MWFeedParser und SVProgressHUD, und zwei Eigenschaften angeben, Episoden und feedParser. Wir müssen auch machen MTViewController sich an die anpassen MWFeedParserDelegate Protokoll.

 #import "MTViewController.h" #import "MWFeedParser.h" #import "SVProgressHUD.h" @interface MTViewController ()  @ property (strong, nonatomic) NSDictionary * Podcast; @property (starke, nichtatomare) NSMutableArray * -Episoden; @ property (strong, nonatomic) MWFeedParser * feedParser; @Ende

Als nächstes aktualisieren wir setPodcast: durch Anrufen fetchAndParseFeed, eine Hilfsmethode, in der wir das verwenden MWFeedParser Klasse, um den Feed des Podcasts abzurufen und zu analysieren.

 - (void) setPodcast: (NSDictionary *) Podcast if (_podcast! = Podcast) _podcast = Podcast; // Ansicht aktualisieren [self updateView]; // Abruf- und Analyse-Feed [self fetchAndParseFeed]; 

Im fetchAndParseFeed, wir werden unseren Strom los MWFeedParser Instanz, wenn wir eine haben und eine neue Instanz mit der Feed-URL des Podcasts initialisieren. Wir setzen die feedParseType Eigentum an ParseTypeFull und legen Sie den View-Controller als Delegat des Feed-Parsers fest. Bevor wir den Feed abholen, verwenden wir SVProgressHUD um dem Benutzer ein Fortschritts-HUD anzuzeigen.

 - (void) fetchAndParseFeed if (! self.podcast) return; NSURL * url = [NSURL URLWithString: [self.podcast objectForKey: @ "feedUrl"]]; if (! url) return; if (self.feedParser) [self.feedParser stopParsing]; [self.feedParser setDelegate: nil]; [self setFeedParser: nil];  // Episoden löschen if (self.episodes) [self setEpisodes: nil];  // Feed Parser initialisieren self.feedParser = [[MWFeedParser-Zuordnung] initWithFeedURL: url]; // Feed Parser konfigurieren [self.feedParser setFeedParseType: ParseTypeFull]; [self.feedParser setDelegate: self]; // Fortschritt anzeigen HUD [SVProgressHUD showWithMaskType: SVProgressHUDMaskTypeGradient]; // Parsing starten [self.feedParser parse]; 

Wir müssen auch zwei Methoden des implementieren MWFeedParserDelegate Protokoll, feedParser: didParseFeedItem: und feedParserDidFinish:. Im feedParser: didParseFeedItem:, wir initialisieren das Episoden Wenn nötig, geben Sie das Objekt an, das der Feed-Parser uns übergibt.

 - (void) feedParser: (MWFeedParser *) Parser didParseFeedItem: (MWFeedItem *) item if (! self.episodes) self.episodes = [NSMutableArray-Array];  [self.episodes addObject: item]; 

Im feedParserDidFinish:, Wir verwerfen das Fortschritts-HUD und aktualisieren die Tabellenansicht. Sagten Sie Tabellenansicht? Stimmt. Wir müssen eine Tabellenansicht hinzufügen und das Notwendige implementieren UITableViewDataSource Protokollmethoden.

 - (void) feedParserDidFinish: (MWFeedParser *) Parser // Progress-HUD für Fortschrittsanzeige [SVProgressHUD-Abweisung]; // Ansicht aktualisieren [self.tableView reloadData]; 

Schritt 3: Anzeigen des Feeds

Bevor Sie die Benutzeroberfläche aktualisieren, öffnen Sie sie MTViewController.h, deklarieren Sie einen Ausgang für die Tabellensicht und teilen Sie dem Compiler mit MTViewController Klasse entspricht der UITableViewDataSource und UITableViewDelegate Protokolle.

 #einführen  @interface MTViewController: UIViewController  @ property (schwach, nicht atomar) IBOutlet UITableView * tableView; @Ende

Öffnen Sie das Haupt-Storyboard noch einmal und fügen Sie der Ansichts-Controller-Ansicht eine Tabellenansicht hinzu. Verbinden Sie die Tabellenansicht Datenquelle und delegieren Steckdosen mit dem View Controller und verbinden die View Controller Tabellenansicht Auslass mit der Tischansicht. Wählen Sie die Tabellenansicht aus, öffnen Sie die Attribute-Inspektor, und stellen Sie die Anzahl der Prototypzellen auf 1. Wählen Sie die Prototypzelle aus und setzen Sie ihren Stil auf Untertitel, und geben Sie eine Kennung von Folgezelle.


Bevor wir das implementieren UITableViewDataSource Protokoll, deklarieren Sie einen statischen String mit dem Namen Folgezelle im MTViewController.m. Dies entspricht der Kennung, die wir für die Prototypzelle im Storyboard festgelegt haben.

 statischer NSString * EpisodeCell = @ "EpisodeCell";

Implementierung der UITableViewDataSource Das Protokoll ist sehr einfach und ähnelt sehr der Implementierung des Protokolls im Suchansicht-Controller. Der einzige Unterschied ist der Episoden Variable enthält Instanzen von MWFeedItem Klasse statt NSDictionary Instanzen.

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.episodes? 1: 0; 
 - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) Abschnitt return self.episodes? self.episodes.count: 0; 
 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: EpisodeCell forIndexPath: indexPath]; // Feedelement abrufen MWFeedItem * feedItem = [self.episodes objectAtIndex: indexPath.row]; // Table View Cell konfigurieren [cell.textLabel setText: feedItem.title]; [cell.detailTextLabel setText: [NSString stringWithFormat: @ "% @", feedItem.date]]; zurück Zelle; 
 - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO; 
 - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO; 

Führen Sie die Anwendung im iOS-Simulator oder auf einem physischen Gerät aus und führen Sie die einzelnen Schritte durch. Sie sollten jetzt in der Lage sein, nach Podcasts zu suchen, einen Podcast aus der Liste auszuwählen und seine Folgen zu sehen.


Fazit

Wir haben viel in diesem Tutorial gemacht, aber wir haben noch einiges an Arbeit vor uns. Im nächsten Tutorial vergrößern wir