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.
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 NSURLSession
Out-of-Process-API. Wir haben eine Menge zu tun, also lassen Sie uns keine Zeit verlieren und beginnen Sie.
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.
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.
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.
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
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.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.
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;
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];
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];
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. 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"];
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+.
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.
Ö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];
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.
Wir haben viel in diesem Tutorial gemacht, aber wir haben noch einiges an Arbeit vor uns. Im nächsten Tutorial vergrößern wir