web-dev-qa-db-fra.com

NSURL Délégué de session vs complétionHandler

J'ai toujours utilisé des gestionnaires de complétion. Avec NSURLConnection et maintenant avec NSURLSession. Cela a conduit à ce que mon code soit vraiment désordonné, en particulier j'ai une demande dans la demande dans la demande.

Je voulais essayer d'utiliser des délégués dans NSURLSession pour implémenter quelque chose que j'ai fait de façon désordonnée avec NSURLConnection.

J'ai donc créé un NSURLSession et créé un dataTask:

NSURLSessionDataTask *dataTask = [overallSession dataTaskWithURL:url
                                                  completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                      if(error == nil)
                                                      {
                                                          NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                          NSLog(@"Data = %@",text);
                                                      }

                                                  }];

    [dataTask resume];

En ce moment, j'ai un completionHandler pour la réponse, comment pourrais-je passer aux délégués pour gérer la réponse et les données? Et puis-je ajouter un autre dataTask du délégué de celui-ci? Vous utilisez les cookies que ce dataTask a créés et placés dans la session?

20
AndrewSB

Si vous souhaitez ajouter une classe déléguée personnalisée, vous devez implémenter les protocoles NSURLSessionDataDelegate et NSURLSessionTaskDelegate au minimum.

Avec les méthodes:

NSURLSessionDataDelegate - obtenez le statut continu de votre demande

 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {

    receivedData=nil; receivedData=[[NSMutableData alloc] init];
    [receivedData setLength:0];

    completionHandler(NSURLSessionResponseAllow);
}

NSURLSessionDataDelegate

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
   didReceiveData:(NSData *)data {

    [receivedData appendData:data];
}

NSURLSessionTaskDelegate

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
 if (error) {
  // Handle error
 }
else {
   NSDictionary* response=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
    // perform operations for the  NSDictionary response
}

Si vous souhaitez séparer le code délégué (couche intermédiaire) de votre classe appelante (généralement sa bonne pratique d'avoir une classe/couche distincte pour les appels réseau), le délégué de NSURLSession doit être: -

NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:myCustomDelegateClass delegateQueue:nil];

Liens de référence:

  1. Référence de classe NSURLSession
  2. Exemple NSURLSession iOS (HTTP GET, POST, Background Downlads)
  3. De NSURLConnection à NSURLSession
41
Vacca