Aus der Sicht eines Entwicklers ist die Einführung von, eine der wichtigsten Änderungen in iOS 7 und OS X Mavericks NSURLSession
. Obwohl NSURLSession
mag auf den ersten Blick entmutigend erscheinen, es ist wichtig, dass Sie verstehen, was es ist und wie es sich bezieht NSURLConnection
, und was sind die unterschiede. In dieser Serie werde ich Sie durch die Grundlagen von führen NSURLSession
So können Sie diese neue Technologie in Ihren eigenen Anwendungen nutzen.
NSURLConnection
?Die erste Frage, die Sie sich vielleicht stellen, ist, warum Apple es für notwendig hielt, ihn vorzustellen NSURLSession
während wir vollkommen zufrieden sind mit NSURLConnection
. Die eigentliche Frage ist, ob du sind glücklich mit NSURLConnection
. Erinnerst du dich an die Zeit, als du fluchst und Dinge würfst? NSURLConnection
? Die meisten Cocoa-Entwickler waren an diesem Ort, weshalb sich Apple dafür entschieden hat, wieder an das Zeichenbrett zu gehen und eine elegantere Lösung zu entwickeln, die besser für das moderne Web geeignet ist.
Obwohl NSURLSession
und NSURLConnection
Sie haben viel gemeinsam in Bezug auf ihre Funktionsweise. Grundsätzlich sind sie sehr unterschiedlich. Apple erstellt NSURLSession
den allgemeinen Begriffen von NSURLConnection
, Aber das werden Sie im Laufe dieser Serie lernen NSURLSession
ist modern, benutzerfreundlicher und mobiler gebaut.
NSURLSession
?Bevor ich die Unterschiede bespreche NSURLSession
und NSURLConnection
, es ist eine gute idee, zuerst was näher zu betrachten NSURLSession
ist. Trotz seines Namens, NSURLSession
ist nicht nur eine andere Klasse, die Sie in einer iOS- oder OS X-Anwendung verwenden können. NSURLSession
ist in erster Linie eine Technologie wie NSURLConnection
ist.
NSURLSession
und NSURLConnection
Beide bieten eine API für die Interaktion mit verschiedenen Protokollen, z HTTP
und HTTPS
. Das Session-Objekt, eine Instanz von NSURLSession
Klasse, verwaltet diese Interaktion. Es ist ein hoch konfigurierbarer Container mit einer eleganten API, die eine feinkörnige Steuerung ermöglicht. Es bietet Funktionen, die in fehlen NSURLConnection
. Was ist mehr mit NSURLSession
, Sie können Aufgaben erledigen, die mit einfach nicht möglich sind NSURLConnection
, wie privates Browsing implementieren.
Die grundlegende Arbeitseinheit bei der Arbeit mit NSURLSession
ist die Aufgabe, eine Instanz von NSURLSessionTask
. Es gibt drei Arten von Aufgaben, Datenaufgaben, Aufgaben hochladen, und Aufgaben herunterladen.
NSURLSessionDataTask
. Datentasks werden zum Anfordern von Daten von einem Server verwendet, z. B. JSON-Daten. Der Hauptunterschied bei Upload- und Download-Tasks besteht darin, dass Daten direkt an Ihre Anwendung zurückgegeben werden, anstatt das Dateisystem zu durchlaufen. Die Daten werden nur im Speicher gespeichert.NSURLSessionUploadTask
ist eine Unterklasse von NSURLSessionDataTask
und verhält sich auf ähnliche Weise. Einer der Hauptunterschiede zu einer normalen Datenaufgabe besteht darin, dass Upload-Aufgaben in einer Sitzung verwendet werden können, die mit einer Hintergrundsitzungskonfiguration erstellt wurde.NSURLSessionDownloadTask
, erben direkt von NSURLSessionTask
. Der wichtigste Unterschied bei Datenaufgaben besteht darin, dass eine Download-Aufgabe ihre Antwort direkt in eine temporäre Datei schreibt. Dies unterscheidet sich stark von einer normalen Datenaufgabe, die die Antwort im Speicher speichert. Es ist möglich zu stornieren eine Download-Aufgabe und fortsetzen es zu einem späteren Zeitpunkt.Wie Sie sich vorstellen können, ist Asynchronität ein Schlüsselbegriff in NSURLSession
. Das NSURLSession
Die API gibt Daten zurück, indem ein Beendigungshandler oder der Delegat der Sitzung aufgerufen wird. Die API von NSURLSession
wurde im Hinblick auf Flexibilität konzipiert, wie Sie später in diesem Tutorial feststellen werden.
Wie ich schon erwähnt habe, NSURLSession
ist sowohl eine Technologie als auch eine Klasse, mit der Sie arbeiten werden. Das NSURLSession
API enthält jedoch eine Reihe von Klassen NSURLSession
ist die Schlüsselkomponente, die Anforderungen sendet und Antworten empfängt. Die Konfiguration des Sitzungsobjekts wird jedoch von einer Instanz von verwaltet NSURLSessionConfiguration
Klasse. Das NSURLSessionTask
Die Klasse und ihre drei konkreten Unterklassen sind die Worker und werden immer in Verbindung mit einer Sitzung verwendet, da sie die Aufgabenobjekte erstellen.
Beide NSURLSession
und NSURLConnection
verlassen sich stark auf das Delegationsmuster. Das NSURLSessionDelegate
Das Protokoll deklariert eine Handvoll Delegatmethoden für die Behandlung von Ereignissen auf Sitzungsebene. zusätzlich NSURLSessionTask
Klassen und Unterklassen deklarieren jeweils ein Delegatenprotokoll zur Behandlung von Ereignissen auf Taskebene.
Das NSURLSession
API baut auf Klassen auf, mit denen Sie bereits vertraut sind, wie z NSURL
, NSURLAnfrage
, und NSURLResponse
.
Wie geht das NSURLSession
unterscheiden sich von NSURLConnection
? Dies ist eine wichtige Frage, weil NSURLConnection
wird nicht von Apple abgelehnt. Sie können immer noch verwenden NSURLConnection
in Ihren Projekten. Warum sollten Sie verwenden? NSURLSession
?
Das erste, was zu verstehen ist, ist das NSURLSession
Instanz ist das Objekt, das die Anforderung und die Antwort verwaltet. Dies ist ähnlich wie NSURLConnection
funktioniert, der Hauptunterschied besteht jedoch darin, dass die Konfiguration der Anforderung vom Sitzungsobjekt, einem langlebigen Objekt, gehandhabt wird. Dies geschieht durch die NSURLSessionConfiguration
Klasse. Es bietet nicht nur die NSURLSession
Fein abgestimmte API-Konfiguration über die NSURLSessionConfiguration
Diese Klasse fördert die Trennung von Daten (Anfragetext) und Metadaten. Das NSURLSessionDownloadTask
veranschaulicht dies gut, indem die Antwort direkt in das Dateisystem geschrieben wird.
Die Authentifizierung ist einfacher und eleganter durch NSURLSession
. Das NSURLSession
Die API behandelt die Authentifizierung auf Verbindungsbasis und nicht auf Anfrage, wie z NSURLConnection
tut. Das NSURLSession
Die API macht es auch bequemer, HTTP-Optionen bereitzustellen, und jede Sitzung kann einen separaten Speichercontainer haben, je nachdem, wie Sie die Sitzung konfigurieren.
In der Einleitung habe ich Ihnen das gesagt NSURLSession
bietet eine moderne Benutzeroberfläche, die sich nahtlos in iOS 7 integriert. Ein Beispiel für diese Integration ist NSURLSession
Out-of-Process-Uploads und -Downloads. NSURLSession
wurde optimiert, um die Akkulaufzeit zu erhalten, unterstützt das Anhalten, Abbrechen und Wiederaufnehmen von Aufgaben sowie die Multitasking-API von UIKit. Was soll man nicht lieben? NSURLSession
?
Eine neue API lässt sich am besten durch Übung erlernen, also ist es an der Zeit, Xcode zu starten und die Füße nass zu machen. Starten Sie Xcode 5, erstellen Sie ein neues Projekt, indem Sie auswählen Neu> Projekt… von dem Datei Menü und wählen Sie die Einzelansicht-Anwendung Vorlage aus der Liste der iOS-Anwendungsvorlagen.
Geben Sie Ihrem Projekt einen Namen, teilen Sie Xcode mit, wo Sie es speichern möchten, und klicken Sie auf Erstellen. Das Projekt muss nicht unter Quellcodeverwaltung gestellt werden.
Bei der Arbeit mit NSURLSession
, Es ist wichtig zu verstehen, dass das Sitzungsobjekt eine Instanz von NSURLSession
, ist der Starspieler. Es verarbeitet die Anforderungen und Antworten, konfiguriert die Anforderungen, verwaltet den Speicher und den Status der Sitzung usw. Das Erstellen einer Sitzung kann auf verschiedene Arten erfolgen. Der schnellste Weg zum Einstieg ist die Verwendung NSURLSession
's sharedSession
Klassenmethode wie unten gezeigt.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession];
Ein ... kreieren Session
Objekt im View Controller viewDidLoad
Methode wie oben gezeigt. Das Session
Das von uns erstellte Objekt ist für unser Beispiel in Ordnung, aber Sie möchten wahrscheinlich in den meisten Fällen etwas mehr Flexibilität. Das Session
Das Objekt, das wir gerade erstellt haben, verwendet das Globale NSURLCache
, NSHTTPCookieStorage
, und NSURLCredentialStorage
. Dies bedeutet, dass es ähnlich funktioniert wie eine Standardimplementierung von NSURLConnection
.
Um das zu setzen Session
Zu verwendendes Objekt, lassen Sie uns die iTunes Store Search API abfragen und nach von Apple erstellter Software suchen. Die iTunes Store Search API ist einfach zu verwenden und erfordert keine Authentifizierung. Dies macht sie ideal für unser Beispiel.
Um die Such-API abzufragen, müssen wir eine Anfrage an senden https://itunes.apple.com/search
und einige Parameter übergeben. Wie wir zuvor gesehen haben, bei der Verwendung von NSURLSession
API, eine Anforderung wird durch eine Aufgabe dargestellt. Um die Such-API abzufragen, benötigen wir lediglich eine Datenaufgabe, eine Instanz der NSURLSessionDataTask
Klasse. Schauen Sie sich das aktualisierte an viewDidLoad
Implementierung unten gezeigt.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [Sitzung dataTaskWithURL: [NSURL URLWithString: @ "https://itunes.apple.com/search?term=apple&media=software"] completionHandler: ^ (NSData * -Daten, NSURLResponse * -Antwort, NSError * -Fehler) NSDictionary * json = [NSJSONSerialization JSONObjectWithData: Datenoptionen: 0 Fehler: Null]; NSLog (@ "% @", json); ];
Es gibt eine Reihe von Methoden, um eine Aufgabe zu erstellen Session
object übernimmt die eigentliche Erstellung und Konfiguration der Aufgabe. In diesem Beispiel rufen wir auf dataTaskWithURL: completionHandler:
und gib ein Beispiel von NSURL
sowie einen Completion-Handler. Der Beendigungs-Handler akzeptiert drei Argumente, den Rohdaten der Antwort (NSData
), das Antwortobjekt (NSURLResponse
), und ein Fehlerobjekt (NSError
). Wenn die Anforderung erfolgreich ist, wird das Fehlerobjekt angezeigt Null
. Da wir wissen, dass die Anforderung eine JSON-Antwort zurückgibt, erstellen wir eine Stiftung Objekt aus der Daten
Objekt, das wir erhalten haben, und protokolliert die Ausgabe in der Konsole.
Es ist wichtig zu verstehen, dass die Error
Das an den Completion-Handler übergebene Objekt wird nur gefüllt, nicht Null
, wenn die Anforderung fehlgeschlagen ist oder ein Fehler aufgetreten ist. Mit anderen Worten, wenn die Anforderung zurückgegeben wird a 404
Antwort, die Anfrage war in Bezug auf die Sitzungen erfolgreich. Das Error
Objekt wird dann sein Null
. Dies ist ein wichtiges Konzept, das bei der Arbeit zu verstehen ist NSURLSession
und NSURLConnection
für diese Angelegenheit.
Erstellen Sie das Projekt, führen Sie die Anwendung im iOS-Simulator oder auf einem physischen Gerät aus und überprüfen Sie die Xcode-Konsole. Auf der Konsole wird nichts gedruckt. Was schief gelaufen ist? Wie ich bereits erwähnt habe NSURLSession
Die API unterstützt das Anhalten, Abbrechen und Wiederaufnehmen von Aufgaben oder Anforderungen. Dieses Verhalten ähnelt dem von NSOperation
und es erinnert Sie möglicherweise an die AFNetworking-Bibliothek. Eine Aufgabe hat eine Zustand
Eigenschaft, die angibt, ob die Aufgabe ist Laufen (NSURLSessionTaskStateRunning
), suspendiert (NSURLSessionTaskStateSuspended
), abbrechen (NSURLSessionTaskStateCanceling
), oder abgeschlossen (NSURLSessionTaskStateCompleted
). Wenn ein Sitzungsobjekt eine Aufgabe erstellt, beginnt die Aufgabe im suspendiert Zustand. Um die Aufgabe zu starten, müssen wir es mitteilen fortsetzen
durch anrufen fortsetzen
auf die aufgabe. Aktualisieren Sie die viewDidLoad
Methode wie unten gezeigt, führen Sie die Anwendung noch einmal aus und überprüfen Sie die Ausgabe in der Konsole. Mission erfüllt.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [Sitzung dataTaskWithURL: [NSURL URLWithString: @ "https://itunes.apple.com/search?term=apple&media=software"] completionHandler: ^ (NSData * -Daten, NSURLResponse * -Antwort, NSError * -Fehler) NSDictionary * json = [NSJSONSerialization JSONObjectWithData: Datenoptionen: 0 Fehler: Null]; NSLog (@ "% @", json); ]; [dataTask Lebenslauf];
Im vorherigen Beispiel haben wir einen Completion-Handler verwendet, um die Antwort zu verarbeiten, die wir von der Anfrage erhalten haben. Es ist auch möglich, das gleiche Ergebnis zu erzielen, indem das Task Delegate-Protokoll implementiert wird. Mal sehen, was es braucht, um ein Bild herunterzuladen NSURLSession
und das NSURLSessionDownloadTask
.
Öffnen MTViewController.h
und erstellen Sie zwei Auslässe wie unten gezeigt. Wir verwenden den ersten Ausgang, eine Instanz von UIImageView
, um das heruntergeladene Bild dem Benutzer anzuzeigen. Der zweite Auslass, eine Instanz von UIProgressView
, zeigt den Fortschritt der Download-Aufgabe an.
#einführen@interface MTViewController: UIViewController @property (schwach, nicht atomar) IBOutlet UIImageView * imageView; @ property (schwach, nicht atomar) IBOutlet UIProgressView * progressView; @Ende
Öffnen Sie das Haupt-Storyboard des Projekts (Hauptplatine), ziehen Sie eine UIImageView
Instanz in die Ansicht des View-Controllers ein, und verbinden Sie den soeben erstellten Ausgang des View-Controllers in der Header-Datei des View-Controllers. Wiederholen Sie diesen Vorgang für die Fortschrittsansicht.
In diesem Beispiel machen wir keinen Gebrauch von sharedSession
Klassenmethode, weil wir das konfigurieren müssen Session
Objekt, das wir verwenden, um die Anfrage zu stellen. Aktualisieren Sie die Implementierung von viewDidLoad
Wie nachfolgend dargestellt.
- (void) viewDidLoad [super viewDidLoad]; NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession * session = [NSURLSession sessionWithConfiguration: sessionConfiguration delegate: self delegateQueue: nil]; NSURLSessionDownloadTask * downloadTask = [session downloadTaskWithURL: [NSURL URLWithString: @ "http://cdn.tutsplus.com/mobile/uploads/2013/12/sample.jpg"]]; [downloadTask-Lebenslauf];
Um zu verhindern, dass eine Warnung des Compilers angezeigt wird, müssen Sie die entsprechende Einstellung vornehmen MTViewController
Klasse zum NSURLSessionDelegate
und NSURLSessionDownloadDelegate
Protokolle wie unten gezeigt.
#import "MTViewController.h" @interface MTViewController ()@Ende
Im viewDidLoad
, wir erstellen eine Instanz von NSURLSessionConfiguration
Klasse durch Aufrufen der defaultSessionConfiguration
Klassenmethode. Wie in der Dokumentation angegeben, verhält sich die Sitzung bei Verwendung der Standardsitzungskonfiguration wie eine Instanz von NSURLConnection
in der Standardkonfiguration, was für unser Beispiel in Ordnung ist.
In diesem Beispiel erstellen wir eine NSURLSession
Instanz durch Aufrufen der sessionWithConfiguration: delegate: delegateQueue:
Klassenmethode und übergeben Sie die sessionConfiguration
Objekt, das wir vor einem Moment erstellt haben. Wir setzen den View Controller als Sitzungsdelegierten und bestanden Null
als drittes Argument. Sie können das dritte Argument vorerst ignorieren. Der Hauptunterschied zum vorherigen Beispiel besteht darin, dass wir das setzen Session
Delegierte an den View Controller.
Um das Bild herunterzuladen, müssen Sie eine Download-Aufgabe erstellen. Wir machen das, indem wir anrufen downloadTaskWithURL:
auf der Session
Objekt, das eine Instanz von NSURL
, und anrufen fortsetzen
auf der Download-Aufgabe. Wir hätten einen Fertigstellungs-Handler wie zuvor verwenden können, aber ich möchte Ihnen die Möglichkeiten zeigen, stattdessen einen Delegierten zu verwenden.
Damit dies alles funktioniert, müssen wir die drei Delegatmethoden des NSURLSessionDownloadDelegate
Protokoll, URLSession: downloadTask: didFinishDownloadingToURL:
, URLSession: downloadTask: didResumeAtOffset: expectedTotalBytes:
, und URLSession: downloadTask: downloadTask didWriteData: totalBytesWritten: totalBytesExpectedToWrite:
. Die Implementierung jeder Methode ist recht einfach. Es ist wichtig zu wissen, dass wir die Benutzeroberfläche des Hauptthreads mit GCD (Grand Central Dispatch) aktualisieren müssen. Durchgehen Null
als drittes Argument von sessionWithConfiguration: delegate: delegateQueue:
, Das Betriebssystem hat eine Hintergrundwarteschlange für uns erstellt. Dies ist in Ordnung, bedeutet aber auch, dass wir wissen müssen, dass die Delegat-Methoden in einem Hintergrundthread anstelle des Hauptthreads aufgerufen werden. Erstellen Sie das Projekt und führen Sie die Anwendung aus, um das Ergebnis unserer harten Arbeit zu sehen.
- (void) URLSession: (NSURLSession *) Sitzung downloadTask: (NSURLSessionDownloadTask *) downloadTask didFinishDownloadingToURL: (NSURL *) location NSData * data = [NSData dataWithContentsOfURL: location]; dispatch_async (dispatch_get_main_queue (), ^ [self.progressView setHidden: YES]; [self.imageView setImage: [UIImage imageWithData: data]];); - (void) URLSession: (NSURLSession *) Sitzung downloadTask: (NSURLSessionDownloadTask *) downloadTask didResumeAtOffset: (int64_t) fileOffset expectedTotalBytes: (int64_t) erwartetTotalBytes - (void) URLSession: (NSURLSachr. downloadTask didWriteData: (int64_t) bytesWritten totalBytesWritten: (int64_t) totalBytesWritten totalBytesExpectedToWrite: (int64_t) totalBytesExpectedToWrite float progress = (doppelt) totalBytesWritten / (double) totalBytesExpt. dispatch_async (dispatch_get_main_queue (), ^ [self.progressView setProgress: progress];);
Mit diesen zwei Beispielen sollten Sie ein grundlegendes Verständnis für die Grundlagen der NSURLSession
API, wie es zu vergleichen ist NSURLConnection
, und was sind die Vorteile. Im nächsten Teil dieser Serie werden wir uns mit den fortgeschritteneren Funktionen von NSURLSession
.