Du point de vue du développeur, l’un des changements les plus significatifs dans iOS 7, et OS X Mavericks, est l’introduction de NSURLSession
. Même si NSURLSession
peut sembler intimidant au premier abord, il est important que vous compreniez ce que c'est, comment ça se rapporte NSURLConnection
, et quelles sont les différences. Dans cette série, je vais vous présenter les principes fondamentaux de NSURLSession
afin que vous puissiez tirer parti de cette nouvelle technologie dans vos propres applications.
NSURLConnection
?La première question que vous vous posez peut-être est de savoir pourquoi Apple a jugé nécessaire de présenter NSURLSession
alors que nous sommes parfaitement heureux avec NSURLConnection
. La vraie question est de savoir si vous sont heureux avec NSURLConnection
. Vous souvenez-vous du moment où vous avez maudit et jeté des choses à NSURLConnection
? La plupart des développeurs de Cocoa se sont rendus à cet endroit. C'est pourquoi Apple a décidé de revenir au tableau et de créer une solution plus élégante, mieux adaptée au Web moderne.
Même si NSURLSession
et NSURLConnection
ont beaucoup en commun en ce qui concerne la façon dont ils travaillent, à un niveau fondamental, ils sont très différents. Apple a créé NSURLSession
ressembler aux concepts généraux de NSURLConnection
, mais vous apprendrez au cours de cette série que NSURLSession
est moderne, facile à utiliser et conçu pour le mobile.
NSURLSession
?Avant de discuter des différences entre NSURLSession
et NSURLConnection
, c'est une bonne idée de regarder d'abord de plus près ce que NSURLSession
est. Malgré son nom, NSURLSession
n'est pas simplement une autre classe que vous pouvez utiliser dans une application iOS ou OS X. NSURLSession
est avant tout une technologie au même titre que NSURLConnection
est.
NSURLSession
et NSURLConnection
les deux fournissent une API pour interagir avec divers protocoles, tels que HTTP
et HTTPS
. L'objet de session, une instance de NSURLSession
classe, est ce qui gère cette interaction. Il s’agit d’un conteneur hautement configurable avec une API élégante qui permet un contrôle précis. Il offre des fonctionnalités qui sont absentes dans NSURLConnection
. De plus, avec NSURLSession
, vous pouvez accomplir des tâches qui ne sont tout simplement pas possibles avec NSURLConnection
, comme la mise en œuvre de la navigation privée.
L'unité de travail de base lorsque vous travaillez avec NSURLSession
est la tâche, une instance de NSURLSessionTask
. Il y a trois types de tâches, tâches de données, télécharger des tâches, et tâches de téléchargement.
NSURLSessionDataTask
. Les tâches de données sont utilisées pour demander des données à un serveur, telles que des données JSON. La principale différence entre les tâches de téléchargement et de téléchargement est qu'elles renvoient des données directement à votre application au lieu de passer par le système de fichiers. Les données ne sont stockées qu'en mémoire.NSURLSessionUploadTask
est une sous-classe de NSURLSessionDataTask
et se comporte de la même manière. L'une des principales différences avec une tâche de données classique est que les tâches de téléchargement peuvent être utilisées dans une session créée avec une configuration de session en arrière-plan..NSURLSessionDownloadTask
, hériter directement de NSURLSessionTask
. La différence la plus significative avec les tâches de données est qu'une tâche de téléchargement écrit sa réponse directement dans un fichier temporaire. Ceci est très différent d'une tâche de données normale qui stocke la réponse en mémoire. Il est possible de Annuler une tâche de téléchargement et CV plus tard.Comme vous pouvez l’imaginer, l’asynchronisme est un concept clé dans NSURLSession
. le NSURLSession
L'API renvoie des données en appelant un gestionnaire de complétion ou par l'intermédiaire du délégué de la session. L'API de NSURLSession
a été conçu pour être flexible, comme vous le remarquerez un peu plus tard dans ce tutoriel.
Comme je l'ai mentionné plus tôt, NSURLSession
est à la fois une technologie et une classe avec laquelle vous travaillerez. le NSURLSession
L’API héberge un certain nombre de classes, mais NSURLSession
est le composant clé qui envoie les demandes et reçoit les réponses. Cependant, la configuration de l’objet de session est gérée par une instance de NSURLSessionConfiguration
classe. le NSURLSessionTask
La classe et ses trois sous-classes concrètes sont les travaux et sont toujours utilisées conjointement avec une session car c'est la session qui crée les objets de tâche..
Tous les deux NSURLSession
et NSURLConnection
repose fortement sur le modèle de délégation. le NSURLSessionDelegate
Le protocole déclare une poignée de méthodes déléguées pour le traitement des événements au niveau de la session. De plus, le NSURLSessionTask
les classes et sous-classes déclarent chacune un protocole délégué pour la gestion des événements au niveau des tâches.
le NSURLSession
L'API repose sur les classes que vous connaissez déjà, telles que NSURL
, NSURLDemande
, et NSURLResponse
.
Comment NSURLSession
différer NSURLConnection
? C’est une question importante, car NSURLConnection
n'est pas obsolète par Apple. Vous pouvez toujours utiliser NSURLConnection
dans vos projets. Pourquoi devriez-vous utiliser NSURLSession
?
La première chose à comprendre est que le NSURLSession
instance est l'objet qui gère la demande et la réponse. Ceci est similaire à la façon dont NSURLConnection
fonctionne, mais la principale différence est que la configuration de la demande est gérée par l'objet de session, qui est un objet de longue durée. Cela se fait à travers le NSURLSessionConfiguration
classe. Non seulement il fournit la NSURLSession
API configuration fine à travers le NSURLSessionConfiguration
classe, il encourage la séparation des données (corps de la demande) et des métadonnées. le NSURLSessionDownloadTask
illustre bien ceci en écrivant directement la réponse dans le système de fichiers.
L’authentification est plus facile et gérée plus élégamment par NSURLSession
. le NSURLSession
L'API gère l'authentification sur une base de connexion plutôt que sur une base de demande, comme NSURLConnection
Est-ce que. le NSURLSession
L'API facilite également la fourniture d'options HTTP et chaque session peut avoir un conteneur de stockage distinct en fonction de la configuration de la session..
Dans l'introduction, je vous ai dit que NSURLSession
fournit une interface moderne, qui s'intègre harmonieusement à iOS 7. Un exemple de cette intégration est NSURLSession
Les envois et téléchargements hors processus. NSURLSession
est optimisé pour préserver la durée de vie de la batterie, prend en charge les pauses, les annulations et la reprise des tâches, ainsi que l’API multitâche de UIKit. De quoi ne pas aimer NSURLSession
?
Il est préférable d’apprendre une nouvelle API, il est donc temps de lancer Xcode et de nous mouiller les pieds. Lancez Xcode 5, créez un nouveau projet en sélectionnant Nouveau> Projet… du Fichier menu et sélectionnez le Application à vue unique modèle de la liste des modèles d'application iOS.
Donnez un nom à votre projet, dites à Xcode où vous souhaitez l’enregistrer, puis appuyez sur Créer. Il n'est pas nécessaire de placer le projet sous contrôle de source.
Quand on travaille avec NSURLSession
, il est important de comprendre que l'objet de session, une instance de NSURLSession
, est le joueur star. Il traite les demandes et les réponses, configure les demandes, gère le stockage et l'état de la session, etc. La création d'une session peut s'effectuer de plusieurs manières. Le moyen le plus rapide de commencer est d’utiliser NSURLSession
de session partagée
méthode de classe comme indiqué ci-dessous.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession];
Créer un session
objet dans le contrôleur de vue viewDidLoad
méthode indiquée ci-dessus. le session
L'objet que nous avons créé convient à notre exemple, mais vous souhaitez probablement un peu plus de flexibilité dans la plupart des cas. le session
objet que nous venons de créer utilise le global NSURLCache
, NSHTTPCookieStorage
, et NSURLCredentialStorage
. Cela signifie que cela fonctionne assez similaire à une implémentation par défaut de NSURLConnection
.
Mettre le session
objet à utiliser, interrogons l'API iTunes Store Search et recherchons les logiciels conçus par Apple. L'API de recherche iTunes Store est facile à utiliser et ne nécessite aucune authentification, ce qui le rend idéal pour notre exemple..
Pour interroger l’API de recherche, nous devons envoyer une demande à https://itunes.apple.com/search
et passer quelques paramètres. Comme nous l’avons vu précédemment, lorsqu’on utilise le NSURLSession
API, une requête est représentée par une tâche. Pour interroger l’API de recherche, il suffit d’une tâche de données, d’une instance du NSURLSessionDataTask
classe. Jetez un coup d'oeil à la mise à jour viewDidLoad
mise en œuvre ci-dessous.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [session dataTaskWithURL: [NSURL URLWithString: @ "http: NSDictionary * json = [NSJSONSerialization JSONObjectWithData: options de données: 0 erreur: nil]; NSLog (@ "% @", json); ];
Il existe un certain nombre de méthodes disponibles pour créer une tâche, mais le concept clé à comprendre est que le session
object effectue la création et la configuration réelles de la tâche. Dans cet exemple, nous appelons dataTaskWithURL: completionHandler:
et passez une instance de NSURL
ainsi qu'un gestionnaire de complétion. Le gestionnaire d’achèvement accepte trois arguments, le données brutes de la réponse (NSData
), la objet de réponse (NSURLResponse
), Et un objet d'erreur (NSError
). Si la requête aboutit, l'objet d'erreur est néant
. Comme nous savons que la demande renvoie une réponse JSON, nous créons un Fondation objet de la Les données
objet que nous avons reçu et connectons la sortie à la console.
Il est important de comprendre que le Erreur
L’objet passé au gestionnaire d’achèvement n’est rempli que, pas néant
, si la demande a échoué ou a rencontré une erreur. En d’autres termes, si la requête renvoie un 404
réponse, la demande a abouti en ce qui concerne les sessions. le Erreur
l'objet sera alors néant
. C’est un concept important à saisir lorsque vous travaillez avec NSURLSession
et NSURLConnection
d'ailleurs.
Générez le projet et exécutez l'application dans iOS Simulator ou sur un périphérique physique, puis inspectez la console Xcode. Rien n'est imprimé sur la console. Qu'est ce qui ne s'est pas bien passé? Comme je l'ai mentionné plus tôt, le NSURLSession
L'API prend en charge la pause, l'annulation et la reprise de tâches ou de demandes. Ce comportement est similaire à celui de NSOperation
et cela peut vous rappeler la bibliothèque AFNetworking. Une tâche a Etat
propriété qui indique si la tâche est fonctionnement (NSURLSessionTaskStateRunning
), suspendu (NSURLSessionTaskStateSuspended
), annulation (NSURLSessionTaskStateCanceling
), ou terminé (NSURLSessionTaskStateCompleted
). Lorsqu'un objet de session crée une tâche, celle-ci commence sa vie dans le suspendu Etat. Pour commencer la tâche, nous devons lui dire CV
en appelant CV
sur la tâche. Mettre à jour le viewDidLoad
comme indiqué ci-dessous, exécutez l'application une fois de plus et inspectez la sortie dans la console. Mission accomplie.
- (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [session dataTaskWithURL: [NSURL URLWithString: @ "http: NSDictionary * json = [NSJSONSerialization JSONObjectWithData: options de données: 0 erreur: nil]; NSLog (@ "% @", json); ]; [dataTask resume];
Dans l'exemple précédent, nous avons utilisé un gestionnaire d'achèvement pour traiter la réponse reçue à partir de la demande. Il est également possible d'obtenir le même résultat en implémentant le (s) protocole (s) de délégation de tâche. Voyons ce qu'il faut pour télécharger une image en tirant parti de NSURLSession
et le NSURLSessionDownloadTask
.
Ouvrir MTViewController.h
et créez deux sorties comme indiqué ci-dessous. Nous allons utiliser le premier point de vente, une instance de UIImageView
, pour afficher l'image téléchargée à l'utilisateur. Le second point de vente, une instance de UIProgressView
, montrera la progression de la tâche de téléchargement.
#importation@interface MTViewController: UIViewController @property (faible, non atomique) IBOutlet UIImageView * imageView; @property (faible, non atomique) IBOutlet UIProgressView * progressView; @fin
Ouvrez le scénario principal du projet (Tableau principal), faites glisser un UIImageView
exemple à la vue du contrôleur de vue et connectez la sortie du contrôleur de vue que nous venons de créer dans le fichier d’en-tête du contrôleur de vue. Répétez cette procédure pour la vue de progression.
Dans cet exemple, nous ne ferons pas usage de la session partagée
méthode de classe, car nous avons besoin de configurer le session
objet que nous allons utiliser pour faire la demande. Mettre à jour la mise en œuvre de viewDidLoad
comme indiqué ci-dessous.
- (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"]]; [télécharger le CV de la tâche];
Pour éviter tout avertissement du compilateur, assurez-vous de respecter le MTViewController
classe à la NSURLSessionDelegate
et NSURLSessionDownloadDelegate
protocoles comme indiqué ci-dessous.
#import "MTViewController.h" @interface MTViewController ()@fin
Dans viewDidLoad
, nous créons une instance du NSURLSessionConfiguration
classe en invoquant le defaultSessionConfiguration
méthode de classe. Comme indiqué dans la documentation, en utilisant la configuration de session par défaut, la session se comportera presque comme une instance de NSURLConnection
dans sa configuration par défaut, ce qui convient à notre exemple.
Dans cet exemple, nous créons un NSURLSession
par exemple en invoquant le sessionWithConfiguration: delegate: delegateQueue:
méthode de classe et passer le sessionConfiguration
objet que nous avons créé il y a un moment. Nous définissons le contrôleur de vue comme délégué de session et passons néant
comme troisième argument. Vous pouvez ignorer le troisième argument pour le moment. La principale différence avec l'exemple précédent est que nous avons défini le paramètre session
le délégué du contrôleur de vue.
Pour télécharger l'image, nous devons créer une tâche de téléchargement. Nous faisons cela en appelant downloadTaskWithURL:
sur le session
objet, en passant une instance de NSURL
, et appeler CV
sur la tâche de téléchargement. Nous aurions pu utiliser un gestionnaire d'achèvement comme nous l'avons fait plus tôt, mais je veux vous montrer les possibilités d'utiliser un délégué à la place..
Pour que tout cela fonctionne, nous devons implémenter les trois méthodes de délégation du NSURLSessionDownloadDelegate
protocole, URLSession: downloadTask: didFinishDownloadingToURL:
, URLSession: downloadTask: didResumeAtOffset: attenduTotalBytes:
, et URLSession: downloadTask: downloadTask didWriteData: totalBytesWritten: totalBytesExpectedToWrite:
. La mise en œuvre de chaque méthode est assez facile. Il est important de noter que nous avons besoin de mettre à jour l'interface utilisateur sur le thread principal à l'aide de GCD (Grand Central Dispatch). En passant néant
comme troisième argument de sessionWithConfiguration: delegate: delegateQueue:
, le système d'exploitation a créé une file d'attente en arrière-plan pour nous. C'est correct, mais cela signifie également que nous devons savoir que les méthodes de délégation sont appelées sur un thread d'arrière-plan au lieu du thread principal. Construisez le projet et lancez l'application pour voir le résultat de notre dur labeur.
- (void) URLSession: (NSURLSession *) session 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 *) session downloadTask: (NSURLSessionDownloadTask *) downloadTask didResumeAtOffset: (int64_t) fileOffset attendueTotalBytes: (int64_t) attendueTotalBytes - (void) URLSession (en cours) (env. downloadTask didWriteData: (int64_t) bytesWritten totalBytesWritten: (int64_t) totalBytesWritten totalBytesExpectedToWrite: (int64_t) totalBytesExpectedToWrite progression du flottement = (double) totalBytesWritten / (double) totalBytes dispatch_async (dispatch_get_main_queue (), ^ [self.progressView setProgress: progress];);
Avec ces deux exemples, vous devriez avoir une compréhension de base des principes fondamentaux de la NSURLSession
API, comment elle se compare à NSURLConnection
, et quels sont ses avantages. Dans la prochaine partie de cette série, nous examinerons des fonctionnalités plus avancées de NSURLSession
.