web-dev-qa-db-fra.com

NSURLRequest: Publier des données et lire la page publiée

Sous iOS (cible actuelle 5.0, Base SDK 5.1), comment puis-je envoyer une demande de publication à un serveur, puis lire le contenu de la page. Par exemple, la page utilise un nom d'utilisateur et un mot de passe, puis renvoie echos true ou false. Ceci est juste pour une meilleure compréhension de NSURLRequest.

Merci d'avance!

17
Agent 404

Quelques choses d'abord

  • Décidez comment vous voulez coder vos données - le codage JSON ou url est un bon début.
  • Décidez de la valeur de retour - sera-t-il 1, VRAI ou 0, FAUX, ou même OUI/non nul rien/nul. 
  • Lisez sur le système de chargement URL , c'est votre ami. 

Essayez de rendre toutes vos connexions url asynchrones afin que votre interface utilisateur reste réactive. Vous pouvez le faire avec les rappels NSURLConnectionDelegate. NSURLConnection a un petit inconvénient: votre code doit être découplé. Toutes les variables que vous souhaitez voir disponibles dans les fonctions de délégation devront être enregistrées dans ivars ou dans userInfo dict de votre requête. 

Vous pouvez également utiliser GCD, qui, associé aux qualificatifs __block, vous permet de spécifier le code d'erreur/retour au moment où vous le déclarez - utile pour les extractions uniques. 

Sans plus tarder, voici un encodeur d'URL rapide et sale: 

- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
      NSMutableArray *parts = [[NSMutableArray alloc] init];
      for (NSString *key in dictionary) {
        NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
        NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
        [parts addObject:part];
      }
      NSString *encodedDictionary = [parts componentsJoinedByString:@"&"];
      return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
    }

L'utilisation d'une bibliothèque JSON telle que JSONKit facilite le codage, pensez-y!

Méthode 1 - Rappels asynchrones NSURLConnectionDelegate:

// .h
@interface ViewController : UIViewController<NSURLConnectionDelegate>
@end

// .m
@interface ViewController () {
  NSMutableData *receivedData_;
}
@end

...

- (IBAction)asyncButtonPushed:(id)sender {
  NSURL *url = [NSURL URLWithString:@"http://localhost/"];
  NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username", 
                            @"password", @"password", nil];
  NSData *postData = [self encodeDictionary:postDict];

  // Create the request
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  [request setHTTPMethod:@"POST"];
  [request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
  [request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [request setHTTPBody:postData];

  NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                                                                delegate:self];

  [connection start];  
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  [receivedData_ setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
  [receivedData_ appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  NSLog(@"Succeeded! Received %d bytes of data", [receivedData_ length]);
  NSString *responeString = [[NSString alloc] initWithData:receivedData_
                                                  encoding:NSUTF8StringEncoding];
  // Assume lowercase 
  if ([responeString isEqualToString:@"true"]) {
    // Deal with true
    return;
  }    
  // Deal with an error
}

Méthode 2 - Fonction asynchrone Grand Central Dispatch:

// .m
- (IBAction)dispatchButtonPushed:(id)sender {

  NSURL *url = [NSURL URLWithString:@"http://www.Apple.com/"];
  NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username", 
                            @"password", @"password", nil];
  NSData *postData = [self encodeDictionary:postDict];

  // Create the request
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  [request setHTTPMethod:@"POST"];
  [request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
  [request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [request setHTTPBody:postData];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Peform the request
    NSURLResponse *response;
    NSError *error = nil;
    NSData *receivedData = [NSURLConnection sendSynchronousRequest:request  
                                           returningResponse:&response
                                                       error:&error];    
    if (error) {
      // Deal with your error
      if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
        NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error);
        return;
      }
      NSLog(@"Error %@", error);
      return;
    }

    NSString *responeString = [[NSString alloc] initWithData:receivedData
                                                    encoding:NSUTF8StringEncoding];
    // Assume lowercase 
    if ([responeString isEqualToString:@"true"]) {
      // Deal with true
      return;
    }    
    // Deal with an error

    // When dealing with UI updates, they must be run on the main queue, ie:
    //      dispatch_async(dispatch_get_main_queue(), ^(void){
    //      
    //      });
  }); 
}

Méthode 3 - Utiliser une fonction de commodité NSURLConnection

+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler

J'espère que cela t'aides.

60
Matt Melton
  NSData *postData = [someStringToPost dataUsingEncoding:NSUTF8StringEncoding];

  NSURL *url = [NSURL URLWithString:someURLString];
  NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
  [req setHTTPMethod:@"POST"];
  [req setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
  [req setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [req setHTTPBody:postData];

  NSError *err = nil;
  NSHTTPURLResponse *res = nil;
  NSData *retData = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];
  if (err)
  {
    //handle error
  }
  else
  {
    //handle response and returning data
  }
5
Kai Huppmann

Ce projet pourrait être assez pratique pour vous. Il s'occupera de vos téléchargements et les stockera localement. Consultez le lien https://github.com/amitgowda/AGInternetHandler

0
VIP-DEV